翻译自:https://docs.keydb.dev/blog/2020/04/15/blog-post/
随着Redis 6多线程I/O的出现,该博客比较了Elasticache,KeyDB和Redis 6.0的单节点性能。我们将研究不同负载和不同工具下的吞吐量和时延。
背景介绍
KeyDB大约是在一年前作为Redis的分支引入的,通过多线程实现显著的性能提升。不久之后,亚马逊宣布了含有增强io处理Redis内核的Elasticache。Redis最近也发布了支持多线程io的6.0版。与Redis6和Elasticache不同,KeyDB在多个方面进行多线程处理,包括将event loop放在多个线程上,network IO和query parsing能并发执行。
因此,有3家公司提供了3种产品,它们彼此兼容,并且基于开源Redis:Elasticache是优化的Redis服务;RedisLabs和Redis提供了核心代码和商用软件,而KeyDB是更快速、拥有更多新技术的开源Redis的超集。该博客聚焦性能对比,但末尾有一节也概述了其他一些关键差异。
性能测试
我们使用Memtier和YCSB进行测试。Memtier是RedisLabs开发的一个性能测试工具,YCSB是雅虎用来比较众多热数据库的性能测试工具。我们没有使用KeyDB自己开发的性能测试工具,从而避免出现主观偏差,同时也是因为本次测试的吞吐量限制。本次测试的结果都可以通过AWS重现。该博客末尾有一节详细介绍了如何重现测试以及需要考虑的因素,从而避免出现瓶颈和测试差异。
Memtier的吞吐量测试
Memtier是RedisLabs设计的用于对Redis进行负载测试的性能测试工具。它擅长产生高吞吐量,并且还与KeyDB和Elasticache兼容。以下测试在几种不同大小的AWS r5实例上运行。
我们测试8个线程的KeyDB和8个IO线程的Redis,发现4个IO线程以上的Redis在性能上看不到进一步的提高。但是我们尝试了不同的组合,并使用线程数显示最佳吞吐量。
Elasticache是由AWS管理的一项服务,因此我们留给AWS来优化其配置。
所有测试均在同一AZ内的private IP上进行,并取数次测试的平均值。此博客的末尾可以看到有关重现这些性能测试的详细信息。
下图显示了QPS测试数据:
如图所见,随着更多cpu的使用,KeyDB显示出与Redis和Elasticache相比显著的QPS提高。即使Redis6使用多线程IO,它仍然落后于KeyDB和Elasticache,垂直扩展能力较低。
在r5.large实例上,Elasticache的性能略高,但是我们注意到Elasticache在r5.xlarge上的性能反而下降了(在不同时间进行了多次测试)。我们不确定背后的原因。
用memtier测出的时延都在几毫秒,因为它是计算机/节点在最大吞吐量时测得,不能代表平均负载甚至是高负载时的时延。为了在测试时延方面进行良好的相对比较,我们使用YCSB在给定的负载和吞吐量下测试时延。
使用YCSB进行吞吐量测试
YCSB是Yahoo的性能测试工具,与当今许多流行的数据库兼容。该工具有很大的灵活性,可以使用不同的“工作负载”来表示更多实际的加载场景。
以下测试着眼于运行几种不同工作负载时的最大吞吐量:
负载A:大量更新(读/写50:50)
负载B:大量读取(95:5读/写)
负载C:只读
负载D:读取最新记录-新增记录最热
负载E:短程,比如对话
负载F:读-修改-写
下表显示了预加载以上负载数据集的最大QPS。“加载操作/秒”来自加载负载“ a”数据集。根据YCSB建议,此数据集用于所有负载测试
通过YCSB的测试数据,KeyDB在每个测试的负载下都有最高的吞吐量。Elasticache位居第二,其次是Redis6。可以注意到,Redis6仍然比没有多线程IO的Redis5要快。
YCSB的时延测试
YCSB是衡量时延的出色工具。它可以指定目标吞吐量,并测量与该流量相关的延迟。在不同的负载下,它可以很好地了解数据库在不同流量和不同负载下的性能。在选择要与实例一起使用的计算机大小时,它也有很大帮助。
下面的测试针对的是读/写为50/5的“负载a”和大部分为写的“负载b”。UPDATE和READ的有相似的时延曲线。在运行内存数据库时,通常会使用这些负载。时延测量单位为微秒,数值越低越好
上面显示的曲线表明,随着实例接近其最大吞吐量,时延会显著增加。与Redis6相比,KeyDB可以处理的吞吐量要大得多。与Elasticache相比,KeyDB可以处理的吞吐量也更多,因此能够在较高负载下保持较低的时延。
当处于中等流量时,KeyDB,Elasticache和Redis 6的时延都相似。达到更高的负载时才出现差异。当运行负载a / c / d / e / f时,上述曲线看起来非常相似,但是幅度略有不同。
“负载e”的响应最不同,因此我们还将在下面显示其时延曲线。YCSB所描述的负载e对于“线程对话,每次扫描都是针对指定线程中的消息”而言可能很常见。
如图所见,曲线的趋势类似,但是由于负载的性质,数据集与其他数据集不同。KeyDB仍然保持较低的时延。
火焰图
对于那些喜欢火焰图并寻找某种视觉表示的人,我们在Redis5,Redis6和KeyDB之间运行了一些FlameGraphs。我们无权访问Elasticache服务器,因此无法为其运行它们。这些FlameGraphs在性能测试期间运行。
memtier-redis5,memtier-redis6,memtier-keydb,ycsb-redis5,ycsb-redis6,ycsb-keydb
KeyDB,Elasticache和Redis有哪些不同?
每种产品都是从开源Redis开始构建的,并保持与Redis的完全兼容性。但是每种产品的发展方向都略有不同。因此,除了性能之外,这些产品之间还有哪些其他主要区别?
KeyDB是开源的,专注于内存效率,高吞吐量和性能,并在不久的将来还要进行一些重大改进。这使KeyDB能够提供不被开源Redis接受的一部分功能。KeyDB专注于简化用户体验,比如active replication和multi-master。KeyDB还有其他命令,比如subkey EXPIRES和CRON
KeyDB Pro版本还包括MVCC和FLASH的支持等
Elasticache提供自己的Redis分支作为优化的Redis服,但只能通过AWS提供的付费服务获得,因此无法on Prem使用。由于Redis的实例管理完全由AWS托管,因此Redis副本和集群只能由AWS管理,用户的高级决策有限,配置参数也不受自己的控制。
Redis是开源的,并且使用时间最长。与KeyDB不同,它采用了一切从简的设计和实现理念。
RedisLabs是Redis的付费版本,它提供完全托管的解决方案以及专有模块。RedisLabs提供付费版本的FLASH支持,并且可以on Prem的形式托管,但是价格可能会很高。
多线程差异
尽管Redis6现在具有多线程IO,Elasticache使用其增强的网络IO线程,但KeyDB的工作原理是在多个线程上运行正常的Redis event loop。Network IO和query parsing是同时进行的。每个连接在accept()上分配一个线程。多线程对核心哈希表的访问通过spinlock来保护。因为哈希表的访问非常快,所以spinlock的争用概率比较低。事务在EXEC命令执行的时间内保持锁定。Redis module与GIL协同工作,仅在所有线程都暂停时才获取。这保持了Redis module所期望的原子性保证。
重现性能测试
我们无权通过客户端config get <>来查看Elasticache的配置。但是从设置的角度来看,elasticache依靠副本进行数据备份,并提供诸如“daily backup”之类的功能作为s3的rdb选项。通过查看info persistence, 在性能测试期间没有进行后台保存。为了公平起见,在Redis和KeyDB的性能测试中也禁用了后台保存。
为了优化Redis并遵循其建议,测试中还更新了以下linux参数:
/ proc / sys / net / core / somaxconn更改为65536
echo never > / sys / kernel / mm / transparent_hugepage / enabled
sysctl vm.overcommit_memory = 1
避免瓶颈
- 由于KeyDB的多线程和性能提升,需要比运行一个KeyDB实例大得多的性能测试计算机。需要32核m5.8xlarge才能通过memtier产生足够的吞吐量。这支持多达16个线程KeyDB实例的吞吐量(medium到4xlarge)
- 使用Memtier时,请运行32个线程。
- 在同一网络上运行测试,确保实例位于同一AZ,比如us-east-2a中的两个实例
- 使用private IP运行。如果使用AWS的公共IP,则与网络相关的变化可能更多
- 当心通过代理或VPC运行。使用此类方法,防火墙和其他附加层时,可能很难确定到底是什么瓶颈。最好在简单的环境(在同一vpc内)进行性能测试,然后再添加各层以确保在最优环境下测试。
- 在比较不同的机器实例性能时,确保它们位于相同的AZ中,并尽可能在相近时段进行测试。一天中的网络吞吐量确实会发生变化,所以彼此之间时段接近的测试可以提供最具代表性的相对比较。
- KeyDB是多线程的,确保在运行时指定多个线程
KeyDB
所有的测试都是通过以下参数执行的:
$ keydb-server --protected-mode no --server-threads 7 --server-thread-affinity true --save “”
请记住,安全组不会公开端口6379,而只会向测试实例公开。可以使用--requirepass mypassword参数添加访问密码。
Redis
使用Redis6需要用新的io-threads参数。可以根据需要设置IO线程数。4-8之间的最佳结果,但是在设置时请记住计算机上可用的CPU数量
$ redis-server --protected-mode no --io-threads [#threads] --save “”
Elasticache
可以从这开始:https : //aws.amazon.com/elasticache/。转到“create cluster”并记住以下参数:
- 选择“ Redis”,并确保取消选择“cluster mode enabled”
- 设置实例名称和版本5.0.6(最新)的兼容性
- 选择计算机大小/类型并将副本设置为0
- 选择与性能测试机器相同的AZ
- 一旦创建了机器,就可以使用“primary endpoint”作为主机地址进行连接
Memtier
确保至少在m5.8xlarge上运行。安装memtier并从加载数据集开始
$ memtier_benchmark -s [ip address] –hide-histogram –threads=32 –ratio=1:0
然后使用以下命令运行正常测试:
$ memtier_benchmark -s [ip address] –hide-histogram –threads=32
可以使用其他参数和选项。有关详细信息,请参见--help选项。
YCSB
有关安装YCSB,负载,加载,运行等详细信息,请参阅github存储库和Wiki,以下是用于性能测试的基本命令。
首先加载数据,然后执行测试。默认设置很小,因此需要为测试指定记录数1000万和操作数1000万。
如果性能测试客户端太少的话,可能会对网络延迟比较敏感。为了获得相当一致的结果和最大吞吐量,建议使用350个客户端线程。结果将输出到指定的文件中。
本博客中执行的所有YCSB测试均在r5.4xlarge实例(测试机)上完成,性能测试计算机为m5.8xlarge。