微软基于.NET实现的Redis协议分布式缓存数据库Garnet调研

Source

一、背景:

Redis改了开源协议

Redis在2024-03-21日在twitter上官宣:从Redis 7.4版本开始不再使用BSD开源协议,Redis将获得 SSPLv1 和 RSALv2 的双重许可,简单解读下影响:

  • 各种云厂商只有在与 Redis(Redis 代码的维护者)同意许可条款后才能提供 Redis 7.4。

  • 对于普通开发者、各类公司(非云厂商)的使用不会受到限制。

社区迅速做出了回应:

  • Linux 基金会 3 月 28 日宣布建立 Redis 开源分支,名为“Valkey”,并称这是 Redis 数据存储的开源替代方案

  • 微软研究院也迅速推出一个兼容Redis协议的基于C#实现的高性能分布式数据库Garnet。

Garnet特点介绍:

  • 高性能:基于C#实现的,这个对很多人来说有一些冲击,因为从传统观点看,这是个垃圾回收器语言,性能行不行?从公开数据看相当强悍,后面我们也测试了一把。

  • 兼容性:兼容了Redis RESP协议,兼容了绝大部分Redis命令。

  • 存储分层:多层面的存储支持(内存、SSD、云存储等),底层存储使用微软另一开源项目FASTER实现。如分布式、持久性、一致性等特性。

  • 跨平台:windows和linux均可以使用。

二、性能测试

一般来说,官方测试存在一定量的水分,所以我们也测试了一下看看[坏笑][坏笑]

1、官方给出的性能测试
(1) 官方的说明:Below, we focus on a selected few key results. 这句话亮了[坏笑]

We have tested Garnet thoroughly in a variety of deployment modes:

  • Same local machine for client and server

  • Two local machines - one client and one server

  • Azure Windows VMs

  • Azure Linux VMs

Below, we focus on a selected few key results.

(2) 测试产品:Garnet、Redis 7.2、KeyDB、Dragonfly
  • Garnet配置:

dotnet run -c Release --framework=net8.0 --project Garnet/main/GarnetServer -- \
            --bind $host \
            --port $port \
            --no-pubsub \
            --no-obj \
            --index 1g
  • Redis配置:

./redis-server \
            --bind $host \
            --port $port \
            --logfile "" \
            --save "" \
            --appendonly no \
            --protected-mode no \
            --io-threads 32

其他两个产品可以参考https://microsoft.github.io/garnet/docs/benchmarking/results-resp-bench,这里重点说下Garnet和Redis的测试对比

个人解读:
1、Garnet没有设置线程数:看了下文档,没有设置的话就是机器的核数
2、Redis设置了32个io线程:这个设置就有点扯了。。。32个io线程,worker线程还是一个。不应该对比的是32个单进程单线程吗? 

有兴趣可以搜下这篇文章《是什么让Redis“气急败坏”回击:13年来,总有人想替Redis换套新架构》说的很清楚:Redis官方回击Dragonly,误导性的测试报告。
(3) 测试结果:

可以看出来Garnet对Redis从各个层面是炸裂级的压倒(有些场景吞吐超出了数十倍)

实验一:不同数量客户端会话的吞吐量比较

数据库大小为(a)1024个键及(b)2.56亿个键时,不同数量客户端会话对应的吞吐量(对数坐标)

实验二:不同批量大小的吞吐量比较

数据库大小为(a)1024个键及(b)2.56亿个键时,不同批量大小下的吞吐量比较(取对数坐标)

实验三:不同数量客户端连接数的延迟比较

不同客户端连接数数量时,(a)中位数、(b)第99百分位与(c)第99.9百分位处的延迟水平。

实验四:不同批量大小的延迟比较

不同批量大小下,(a)中位数、(b)第99百分位以及(c)第99.9百分位上的延迟水平

2、自己测试:
(1) 测试环境:
  • 两台同网段机器:一个发压、一台服务端(Redis、Garnet)

  • Redis是8个单线程单进程、Garnet是单进程8线程。

(2) 测试方法:
  • 同等压力下:吞吐、耗时、整机CPU

  • 单个key能力测试

(3) 测试结果:
  • 同等压力测试:

OPS avg latency P50 latency P99 latency P99.9 latency 单机器CPU开销
Redis 653,176 1.64 ms 1.67 ms 1.81 ms 2.49 ms 312%
Garnet 639,845 1.66 ms 1.68 ms 1.83 ms 5.59 ms 919%

解读:两者整体性能和吞吐基本类似,Redis在P99.9略胜一筹,另外Garnet的系统开销(CPU)接近Redis的3倍,猜测是和它多线程的实现有关。

  • 单个key能力:get hello world

OPS
Redis:一个单进程单线程 (因为单个key只能落到一个redis上,所以无法测试8个多进程) 80332
Garnet:一个单进程8线程 638243

解读:Garnet在单key场景性能更强

三、一些问题

1、兼容性问题:

Garnet虽然号称兼容了Redis RESP协议,但目前看有一些功能、命令是不够健全的。

  • 不支持多数据库:虽然这个其实是个比较鸡肋的功能,但是确实也有不少人在用。

  • 不支持Lua:目前看社区是在开发中,但效果看不太好。

  • mset不是原子的:mset应该算一个常用的命令。

  • 没有module和function扩展功能:但自己实现了一套类似的

  • 还有很多命令不支持:PEXPIREAT、RANDOMKEY、RENAMENX、RESTORE、GEO不全、HSTRLEN、LIST、SET、ZSET很多不支持.

官方关于兼容性的说明:

https://microsoft.github.io/garnet/docs/welcome/compatibility

https://www.garnetdocs.top/docs/zh/commands/api-compatibility.html

2、目前看起来还是实验阶段:
Note that Garnet is a research project from Microsoft Research, and the project should be treated as such. That said, we are bunch of highly passionate researchers and developers working on it full-time at the moment to make it as stable and efficient as we can. Our goal is to create a vibrant community around Garnet. In fact, Garnet has been of sufficiently high quality that several first-party and platform teams at Microsoft have deployed versions of Garnet internally for many months now.

四、个人看法

1、Redis改协议对Redis使用者来说不是坏事,目前已经看到开源社区出现了更多的产品(Linux基金会的Valkey、微软的Garnet、之前开源dragonfly)、包括国内开源的kvrocks、tendis、pika等等国内开源产品。

2、Garnet目前还处于实验阶段,有很多不完善的地方,但其分层存储的功能可以在当期降本增效的背景重点关注下。

3、官方测试有些水分,用32个io线程的redis和Garnet比略扯,经测试同等条件下,两者性能接近,多线程版本Garnet在CPU开销上高于多个单进程单线程Redis接近3倍。