EloqKV 作为高性能缓存数据库的优势

在这篇文章中,我们将重点介绍 EloqKV 作为缓存数据库的表现,重点关注其单节点性能。我们会与主流缓存方案 Redis 以及 DragonflyDB 进行比较。(DragonflyDB 是一款支持多线程架构的高性能缓存数据库)。
所有基准测试均在 AWS(us-east-1)的 EC2 实例上进行,操作系统为 Ubuntu 22.04。我们使用 memtier-benchmark 工具生成工作负载。
单节点性能
我们在纯内存模式下对 EloqKV、Redis 和 DragonflyDB 进行了比较,三款数据库均未启用持久化存储和事务功能。需要指出,Redis 和 DragonflyDB 的持久化功能非常有限。Redis 提供日志记录(AOF)和检查点(RDB),但由于性能问题,AOF 很少配置为在每次写入时执行 fsync。RDB 只会定期保存内存中的状态,如果节点崩溃,可能会导致数据丢失。DragonflyDB 仅支持检查点功能,不支持 AOF。由于 Redis 和 DragonflyDB 通常用作内存缓存,我们在相同配置下对 EloqKV 进行基准测试。

我们按照官方文档配置 EloqKV、DragonflyDB 和 Redis。对于 Redis,我们禁用了 AOF 和 RDB 的持久化功能。redis-server --save "" --appendonly no 对于 DragonflyDB,我们只需禁用检查点功能,因为它尚不支持日志记录。dragonfly --dbfilename=对于 EloqKV,我们在 config.ini 文件中禁用了持久存储,并关闭了 WAL(预写日志)功能。
set it to off to turn off persistent storage
enable_data_store=off
set it to off to turn off WAL
enable_wal=off
01.写入负载测试
为了评估 EloqKV 的写入性能,我们使用 memtier_benchmark 以 Put:Get 1:0 的比例(仅写入)运行,配置如下:memtier_benchmark -t client_num -s server_port --distinct-client-seed --ratio=1:0 --key-prefix="kv_" --key-minimum=1 --key-maximum=5000000 --random-data --data-size=128 --hide-histogram --test-time=300
-t:线程数,固定设置为 32。
-c:每个线程的客户端数量。我们配置为 4、8、16 和 32,以评估不同的并发级别。总的并发数分别为 128、256、512 和 1024,计算方法为 thread_num × client_num。
--ratio:写读比率,对于纯写入负载设置为 1:0。
结果
以下是写入专用负载的结果。
X 轴:表示不同的并发级别(thread_num × client_num),模拟不同程度的并发数据库访问。
左 Y 轴:吞吐量,以 KOPS(每秒查询数,单位千)表示。
右 Y 轴:99.9 百分位延迟,以毫秒(ms)表示。

EloqKV 和 DragonflyDB 都优于 Redis,因为它们支持多个工作线程。在不同的并发场景下,EloqKV 提供的吞吐量和延迟几乎与 DragonflyDB 相同,表现出高吞吐量和低延迟。
02. 只读负载测试
对于只读负载,我们调整 memtier-benchmark 的参数,将 Put:Get 比例设置为 0:1。
memtier_benchmark -t $thread_num -c $client_num -s $server_ip -p $server_port --distinct-client-seed --ratio=0:1 --key-prefix="kv_" --key-minimum=1 --key-maximum=5000000 --random-data --data-size=128 --hide-histogram --test-time=300
结果

与写入负载类似,EloqKV 在只读的吞吐量略低于 DragonflyDB,而延迟略高但仍然非常可观。EloqKV 和 DragonflyDB 在吞吐量和延迟方面都显著优于 Redis。
03. 混合负载测试
最后,我们测试了混合负载,设置为 1:10 的 Put:Get 比率:
memtier_benchmark -t $thread_num -c $client_num -s $server_ip -p $server_port --distinct-client-seed --ratio=1:10 --key-prefix="kv_" --key-minimum=1 --key-maximum=5000000 --random-data --data-size=128 --hide-histogram --test-time=300
**--ratio**:设置为 1:10,以进行混合写入-读取操作。
结果

EloqKV 的吞吐量与 DragonflyDB 相似。随着并发性增加,EloqKV 的 P999 延迟略高于 DragonflyDB,但即使在超过一千个并发连接的情况下,延迟仍保持在 4 毫秒以下。
分析与结论
01. 单线程 or 多线程?
EloqKV 和 DragonflyDB 在现代多核服务器上的性能显著优于单进程模型的 Redis。这一差异源于 Redis 的基本设计理念。Redis 将内存数据结构操作限制为单个工作线程,而多个 I/O 线程处理网络和持久性。这种选择虽然大大简化了 Redis 的设计,但自然限制了其在多核系统上的性能。相比之下,EloqKV 和 DragonflyDB 都支持多个工作线程。
关于性能比较是否公平存在许多争论。比如,Redis 在单个服务器节点上支持水平扩展,可以部署为具有多个实例/分片的集群。即使是单线程架构,仍然有优化空间,正如 Valkey 所展示的,后者推动了类似 Redis 的键值存储的性能(https://valkey.io/blog/unlock-one-million-rps)。
尽管如此,随着 CPU 核心数量的增加和查询工作负载的复杂化,我们认为单线程设计面临基本限制。即使 Redis 也在为某些查询探索多线程。Redis 集群的行为与单服务器不同,需要特别关注键分区和负载均衡。
02. 定制优化是必须吗?
与 DragonflyDB 相比,EloqKV 当前缺乏一些优化,例如基于 io_uring 的网络支持。由于这些限制,我们的分析显示,EloqKV 在处理实验工作负载时受到网络栈的制约。即便如此,正如实验所示,EloqKV 在 DragonflyDB 专门设计和优化的工作负载上表现几乎相同。这引出了一个问题,即为有限用例设计特殊数据库软件是否具有盈利性。与 Redis 和 DragonflyDB 不同,EloqKV 远不止是一个单节点内存缓存。它在集群、持久和完全符合 ACID 的事务设置中表现出色。未来的文章中我们将为大家更详细地介绍这些能力。 。EloqKV 基于我们的数据基层技术。我们相信,通过这一革命性技术,用户可以大幅简化数据基础设施,减少对多种专用数据库的需求。
更多详情,欢迎关注“晨章数据”公众号!

评论