今天看到微软研究院开源了一个新的C#项目,叫Garnet,它实现了Redis协议,可以直接将Redis替换为Garnet,客户端不需要任何修改。根据其官网的信息,简单的介绍一下它。

开源仓库地址:https://github.com/microsoft/garnet

文档地址:https://microsoft.github.io/garnet/

Garnet是微软研究院基于C# .NET8.0开发的一种新型远程缓存存储系统,它设计目的是实现极速、可扩展和低延迟。Garnet能够在单节点内进行线程扩展,并支持分片集群执行,具备复制、检查点、故障转移和事务处理功能。它可以在主内存以及分层存储(如SSD和Azure存储)上运行。Garnet提供丰富的API接口和强大的可扩展性模型。

Garnet使用Redis的RESP协议作为其主要通信协议,因此可以使用大多数编程语言中现成的Redis客户端,例如C#中的StackExchange.Redis。与其他开源缓存存储相比,Garnet在性能、延迟、可扩展性和持久性方面都有显著提升。

需要注意的是,Garnet是微软研究院的一个研究项目,应当作为研究项目来对待。尽管如此,我们是一群对此充满热情的研究人员和开发人员,目前正全职工作于此,以使其尽可能稳定和高效。我们的目标是围绕Garnet建立一个活跃的社区。实际上,Garnet的质量已经足够高,以至于微软的几个一线团队和平台团队已经在内部部署了Garnet多个月。

Garnet提供以下主要优势:

  • 与可比的开源缓存存储相比,在小批量和多客户端会话中,服务器吞吐量(每秒操作数)提高了数个数量级。
  • 在标准云端(Azure)机器上,启用加速TCP的情况下,单个操作的极低延迟(在99.9百分位数时常常少于300微秒),适用于Windows和Linux。
  • 随着客户端数量的增加,无论是否客户端批处理,都能实现更好的可伸缩性。
  • 使用单个共享内存服务器实例,可以利用服务器机器的所有CPU/内存资源(无需节点内集群)。
  • 支持超大内存数据集,可以溢出到本地和云存储设备。
  • 具备数据库功能,如快速检查点和恢复,以及发布/订阅。
  • 支持多节点分片哈希分区(Redis "集群"模式)、状态迁移和复制。
  • 经过全面测试,拥有包括Garnet及其存储层Tsavorite在内的数千个单元测试。
  • 一个易于进化和扩展的C#代码库。

性能

上面的简介显示出Garnet有非常多的优点,不过我最关心的是它的性能到底怎么样,看了基准测试的相关结果,总体还是让我非常吃惊,一起来看看性能到底怎么吧。

具体性能测试详情可以查看链接: https://microsoft.github.io/garnet/docs/benchmarking/results-resp-bench

性能测试环境

我们配置了两台运行Linux(Ubuntu 20.04)的Azure Standard F72s v2虚拟机(每台提供72个虚拟CPU和144 GiB内存),并启用了加速TCP功能。这种SKU的好处在于我们可以确保不会与其他虚拟机共置,这将优化性能。其中一台机器运行不同的缓存服务器,另一台专门用于发出工作负载。我们使用名为Resp.benchmark的基准测试工具来生成所有结果。我们将Garnet与撰写本文时最新的开源版本Redis(v7.2)、KeyDB(v6.3.4)和Dragonfly(v6.2.11)进行了比较。在这些实验中,我们使用均匀随机分布的键(Garnet的共享内存设计在倾斜工作负载下的好处更大)。所有数据在这些实验中都适合内存。基准系统根据可用信息进行了尽可能多的调整和优化。下面,我们总结了我们实验中使用的每个系统的启动配置。

基本命令性能

我们通过改变负载大小、批量大小和客户端线程数,对基本的GET/SET操作的吞吐量和延迟进行了测量。在吞吐量实验中,我们在运行实际工作负载之前,先向Garnet预加载一个小型数据库(1024个键)和一个大型数据库(256M个键)。相比之下,我们的延迟实验是在一个空数据库上进行的,并且是对一个小键空间(1024个键)的GET/SET命令的组合工作负载进行的。

吞吐量 GET

在图1所示的实验中,我们使用了大批量的GET操作(每批4096个请求)和小负载(8字节的键和值)来最小化网络开销。随着客户端会话数的增加,我们观察到Garnet的可扩展性比Redis或KeyDB更好。Dragonfly展示了类似的扩展性,尽管只能达到16个线程。还要注意,DragonFly是一个纯内存系统。总的来说,即使数据库大小(即预加载的不同键的数量)更大(达到2.56亿个键)超过了处理器缓存的大小,Garnet的吞吐量相对于其他系统始终更高。



图1:在数据库大小为(a) 1024个键,和(b) 2.56亿个键的情况下,随着客户端会话数的变化,吞吐量(对数尺度)。

即使对于小批量大小,Garnet也通过获得一致更高的吞吐量,超过了竞争系统,如图2所示。这一结果不受实际数据库大小的影响。



图2:在数据库大小为(a) 1024个键,和(b) 2.56亿个键的情况下,随着批量大小的变化,吞吐量(对数尺度)。

延迟 GET/SET

接下来,我们通过发出80%的GET和20%的SET请求的混合体,来测量各种系统的客户端延迟,并将其与Garnet进行比较。因为我们关心的是延迟,所以我们保持数据库大小较小,同时变化工作负载的其他参数,如客户端线程数、批量大小和负载大小。

图3展示了随着客户端会话数的增加,Garnet的延迟(以微秒计)在各个百分位数上都一直较低且更稳定,与其他系统相比。请注意,这个实验不使用批处理。



图3:在不同的客户端会话数下,延迟变化,(a) 中位数,(b) 第99百分位数,和(c) 第99.9百分位数

Garnet的延迟经过了精细调整,以适应客户端的批处理和高效处理查询系统的多个会话。在我们的下一组实验中,我们将批量大小从1增加到64,并在下面的图中以128个活跃客户端连接绘制不同百分位数的延迟。如图4所示,当批量大小增加时,Garnet保持稳定性并实现了比其他系统更低的整体延迟。



图4:在不同的批量大小下,延迟变化,(a) 中位数,(b) 第99百分位数,和(c) 第99.9百分位数

复杂数据结构性能

Garnet 支持大量不同的复杂数据结构,如Hyperloglog、位图、有序集合、列表等。下面,我们将为其中几个精选的数据结构展示性能指标。

Hyperloglog

Garnet支持其内置的Hyperloglog(HLL)数据结构。该结构使用C#实现,支持更新(PFADD)、计算估算值(PFCOUNT)以及合并(PFMERGE)两个或更多不同的HLL结构的操作。HLL数据结构通常在内存占用方面进行优化。我们的实现也不例外,当非零计数数量较低时采用稀疏表示法,超过给定的固定阈值后采用密集表示法,此时内存节省和解压缩所需额外工作之间的权衡已不再吸引人。为并发系统(如Garnet)有效更新HyperLogLog(HLL)结构至关重要。因此,我们的实验特别关注PFADD的性能,并且有意设计了以下情景来压力测试我们的系统:

  • 大量高争用更新(例如,批量大小为4096,数据库键为1024)随着线程数量的增加或有效载荷大小的增加。几次插入后,构建的HyperLogLog(HLL)结构将转为使用密集表示法。
  • 大量低争用更新(例如,批量大小为4096,数据库键为256M)随着线程数量的增加或有效载荷大小的增加。这种调整将增加构建的HyperLogLog(HLL)结构使用稀疏表示法的可能性。因此,我们的测量将考虑处理压缩数据或为非零值递增分配更多空间的额外开销。

在图5中,我们展示了第一个实验场景的结果。Garnet在高争用情况下扩展性非常好,并且在增加线程数量方面的原始吞吐量一致超过其他所有系统。同样,随着有效载荷大小的增加,Garnet 展示了比其他系统更高的总吞吐量。在所有测试的系统中,我们注意到随着有效载荷大小的增加,吞吐量明显下降。由于固有的TCP网络瓶颈,这种行为是预期之中的。



图 5:数据库大小为1024个键时,(a)客户端会话数量增加,(b)有效载荷大小增加的吞吐量(对数刻度)。

图 6显示了上述第二个实验场景的结果。即使在操作HLL稀疏表示时,Garnet的性能也比任何其他系统都要好,并且在增加客户端会话数量时能够实现一致性更高的吞吐量。同样地,对于增加的有效载荷大小,Garnet通过实现整体更高的吞吐量而胜过竞争对手。请注意,在这两种情况下,由于操作压缩数据的开销,吞吐量与之前的实验相比都有所降低。



图 6:数据库大小为1M个键时,(a)客户端会话数量增加,(b)有效载荷大小增加的吞吐量(对数刻度)。

在图 7中,我们进行了与前面所述相同类型的实验,将客户端会话数量固定为64,有效载荷固定为128字节,同时增加批量大小。请注意,即使对于批量大小为4,Garnet的吞吐量增益也明显高于我们测试的任何其他系统。这表明即使对于小批量大小,我们仍然能够胜过竞争对手的系统。



图 7:通过64个客户端会话增加批量大小的吞吐量(对数刻度),对于数据库有(a)1024个键,(b)1M个键。

Bitmap

Garnet支持对字符串数据类型的一系列位操作符。这些操作符可以在常数时间内(例如GETBIT、SETBIT)或线性时间内(例如BITCOUNT、BITPOS、BITOP)进行处理。为了加快处理速度,对于线性时间操作符,我们使用了硬件和SIMD指令。下面我们将呈现这些操作符子集的基准测试结果,包括两种复杂度类别。与之前类似,我们使用小型数据库大小(1024个键)来评估每个系统在高竞争下的性能,同时通过增加有效载荷大小(1MB)避免所有数据常驻CPU缓存。

在图8中,我们展示了GETBIT和SETBIT命令的性能指标。在这两种情况下,随着客户端会话数量的增加,Garnet始终保持较高的吞吐量和更好的可扩展性。



图8:吞吐量(对数刻度),变化的客户端会话数量,对于数据库大小为1024个键和1MB有效载荷。

在图9中,我们评估了BITOP NOT和BITOP AND(有两个源键)对于增加线程数量和1MB有效载荷大小的性能。Garnet在客户端会话数量增加时保持整体更高的吞吐量,与我们测试的每一个其他系统相比。鉴于我们的数据库大小相对较小(即只有1024个键),在高竞争下它也表现得非常好。



图9:吞吐量(对数刻度),变化的客户端会话数量,对于数据库大小为1024个键和1MB有效载荷。

如图10和图11所示,即使对于小批量大小,Garnet也获得了比我们测试的任何其他系统更高的吞吐量。实际上,即使在批量大小为4的情况下,Garnet也显著更快,观察到吞吐量的明显差异并不需要太多。



图10:吞吐量(对数刻度),对于64个客户端会话的不断增加批量大小的数据库,数据库大小为1024个键和1MB有效载荷。



图11:吞吐量(对数刻度),对于64个客户端会话的不断增加批量大小的数据库,数据库大小为1024个键和1MB有效载荷。

总结

上述对Garnet数据库系统的性能测试,包括基本命令的吞吐量和延迟,以及复杂数据结构的性能。在吞吐量测试中,Garnet在预加载不同大小的数据库后,表现出比Redis或KeyDB更好的可扩展性和更高的吞吐量,无论是在小数据库(1024个键)还是大数据库(256M个键)上。延迟测试显示,Garnet在不同客户端会话数下都保持了较低且稳定的延迟。对于复杂数据结构,如Hyperloglog和Bitmaps,Garnet在处理高争用更新和位操作时,也展现了优越的性能和可扩展性。在所有测试中,Garnet的性能通常优于其他系统,即使在数据库大小、客户端会话数量和负载大小等参数变化时也是如此。

C# .NET以其卓越的性能在技术界备受推崇,这一点从TechEmpower的排名以及众多性能测试中都得到了充分的体现。它拥有一系列高效的编程特性,包括结构体、内存操作、unsafe代码块、Span<T>以及async/await等,这些特性极大地提高了代码的执行效率和开发的灵活性。在过去,使用C# .NET技术的构建的中间件产品并不常见,但.NET的这些先进特性已经证明了其在高性能中间件领域的巨大潜力。随着技术的不断进步,我们有理由相信,C# .NET将继续在这一领域展现出更多的可能性,并推动相关技术的发展和创新。

Garnet: 力压Redis的C#高性能分布式存储数据库的更多相关文章

  1. [转帖]谷歌TF2.0凌晨发布!“改变一切,力压PyTorch”

    谷歌TF2.0凌晨发布!“改变一切,力压PyTorch” https://news.cnblogs.com/n/641707/ 投递人 itwriter 发布于 2019-10-01 12:38 评论 ...

  2. Nginx+Lua+Redis整合实现高性能API接口 - 网站服务器 - LinuxTone | 运维专家网论坛 - 最棒的Linux运维与开源架构技术交流社区! - Powered by Discuz!

    Nginx+Lua+Redis整合实现高性能API接口 - 网站服务器 - LinuxTone | 运维专家网论坛 - 最棒的Linux运维与开源架构技术交流社区! - Powered by Disc ...

  3. 总结:如何使用redis缓存加索引处理数据库百万级并发

    前言:事先说明:在实际应用中这种做法设计需要各位读者自己设计,本文只提供一种思想.准备工作:安装后本地数redis服务器,使用mysql数据库,事先插入1000万条数据,可以参考我之前的文章插入数据, ...

  4. 使用redis缓存加索引处理数据库百万级并发

    使用redis缓存加索引处理数据库百万级并发 前言:事先说明:在实际应用中这种做法设计需要各位读者自己设计,本文只提供一种思想.准备工作:安装后本地数redis服务器,使用mysql数据库,事先插入1 ...

  5. 分布式存储数据库的Key的随机分布(RP)和顺序分布(OPP)

    在分布式存储数据库的世界中,无论是基于Key/Value的数据库还是Column Base(比如HBase)的数据库,都有一个重要的因子------Key,或者叫RowKey.我们总是根据Key来快速 ...

  6. Android高性能ORM数据库DBFlow入门

    DBFlow,综合了 ActiveAndroid, Schematic, Ollie,Sprinkles 等库的优点.同时不是基于反射,所以性能也是非常高,效率紧跟greenDAO其后.基于注解,使用 ...

  7. 不同应用共享redis应用,但分数据库存储数据

    日常开发工作中,常常遇到这种情况 项目A ,需要使用redis 项目B ,也需使用redis …… 原来傻乎乎的在服务器上装几个redis,通过不同的端口号来进行使用 其实redis可用有16个数据库 ...

  8. redis不支持多个数据库实例但是支持多个字典

    Redis多个数据库 注意:Redis支持多个数据库,并且每个数据库的数据是隔离的不能共享,并且基于单机才有,如果是集群就没有数据库的概念. Redis是一个字典结构的存储服务器,而实际上一个Redi ...

  9. 三、Redis的配置文件和多数据库用途

    1.使用文件 # 使用配置文件启动 redis-server ./redis.conf # 带配置文件启动 且指定某几个配置 配置名称前加 -- redis-server ./redis.conf - ...

  10. 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!

    为什么80%的码农都做不了架构师?>>>   摘要: 近日,阿里云宣布高性能时间序列数据库 (High-Performance Time Series Database , 简称 H ...

随机推荐

  1. Linux-ln命令创建链接(软连接/硬链接)

    1.ln命令介绍 ln命令可以看作是 link 的缩写,其功能是创建文件间的链接,链接类型包括硬链接(hard link)和软链接(符号链接,symbolic link) 2.ln命令格式 ln 命令 ...

  2. Java基础综合测试

    Java版基础练习题: 输入练习: [问题描述] 任务很简单: 给定若干个整数,请编程输出它们的和. [输入形式] 输入包含多组测试用例. 每组测试数据首先是一个正整数N,表示本组数据有N个整数. 请 ...

  3. NC25045 [USACO 2007 Jan S]Balanced Lineup

    题目链接 题目 题目描述 For the daily milking, Farmer John's N cows (1 ≤ N ≤ 100,000) always line up in the sam ...

  4. NC20154 [JSOI2007]建筑抢修

    题目链接 题目 题目描述 小刚在玩JSOI提供的一个称之为"建筑抢修"的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是T部落的基地里已经有N个建筑设施受到了严 ...

  5. Java I/O 教程(二) 介绍OutputStream 和 InputStream

    OutputStream vs InputStream 我们来看一下两者的工作图: OutputStream 输出流 Java应用程序使用输出流将数据写入到某个目的地,可以是一个文件,数组,外围设备或 ...

  6. 学习go语言编程之常量

    什么在常量 在Golang中,常量是指在编译期就已知且不可改变的值. 字面常量 在程序中硬编码的常量值被称为字面常量,如: -12 // 整数类型常量 3.1415926 // 浮点类型常量 3.2+ ...

  7. 标准运算符替代函数之operator模块

    # 官网参考示例地址 https://docs.python.org/zh-cn/3/library/operator.html # operator模块提供了一套与python的内置的运算符对应的高 ...

  8. eclipse c++ 安装

    eclipse及其插件安装 对于我这种被VS惯坏了的人来说,make file 非常不友好的,最近要在redhat 下面去编译c++动态库和应用程序,原有的工程是在window下面的,要到linux下 ...

  9. 第121篇: DOM常用类型(Document、Element)

    好家伙,本篇为<JS高级程序设计>第十四章"DOM编程"学习笔记   1.Document类型 Document 类型是 JavaScript 中表示文档节点的类型. ...

  10. Jenkins+maven+svn+tomcat持续集成环境

    前言 团队最近要把项目发布的工作拿过来,所以需要一个持续集成发布系统 直接上步骤. 下载 http://mirrors.jenkins-ci.org/war/latest/ 直接下载war包,我下载的 ...