写点什么

是什么让 Redis“气急败坏”回击:13 年来,总有人想替 Redis 换套新架构

  • 2022-08-10
    北京
  • 本文字数:6076 字

    阅读完需:约 20 分钟

是什么让Redis“气急败坏”回击:13年来,总有人想替Redis换套新架构

回击就代表输了?!


今年年中,一位前谷歌、前亚马逊的工程师推出了他创作的开源内存数据缓存系统 Dragonfly,用 C/C++ 编写,基于 BSL 许可(Business Source License)分发。


根据过往的基准测试结果来看, Dragonfly 可能是世界上最快的内存存储系统,它提供了对 Memcached 和 Redis 协议的支持,但能够以更高的性能进行查询,运行时内存消耗也更少。与 Redis 相比,Dragonfly 在典型工作负载下实现了 25 倍的性能提升;单个 Dragonfly 服务器每秒可以处理数百万个请求;在 5GB 存储测试中,Dragonfly 所需的内存比 Redis 少 30%。


作为一个开源软件,Dragonfly 在短短两个月获得了 9.2K GitHub 星,177 个 fork 分支。虽然这些年,涌现了不少类似的 Redis 兼容型内存数据存储系统,例如 KeyDB、Skytable,但是都没能像这次这么“轰动”。毕竟 Redis 诞生了十多年,这时从头开始设计一个缓存系统,可以抛弃历史包袱,更好地利用资源。



为回击新冒头的 Dragonfly,Redis 的联合创始人兼 CTO Yiftach Shoolman 和 Redis Labs 的首席架构师 Yossi Gottlieb、Redis Labs 的性能工程师 Filipe Oliveira 联合发布了一篇名为《13 年后,Redis 是否需要新的架构》的文章。


在文章中,他们特地给出了自认更加公平的 Redis 7.0 vs. Dragonfly 基准测试结果:Redis 的吞吐量比 Dragonfly 高 18% - 40%,以及一些有关 Redis 架构的观点和思考,以证明 “为什么 Redis 的架构仍然是内存实时数据存储(缓存、数据库,以及介于两者之间的所有内容)的最佳架构”。


虽然他们强调 Redis 架构仍然是同类最佳,但也没法忽视 Dragonfly 这些新软件提供的一些新鲜、有趣的想法和技术,Redis 表示其中的一些甚至有可能在未来进入 Redis(比如已经开始研究的 io_uring 、更现代的 dictionaries、更有策略地使用线程等)。


另外,Redis 指出 Dragonfly 基准测试的比较方法 “不能代表 Redis 在现实世界中的运行方式” 。对此,Reddit 上有网友反驳称:


它绝对代表了现实世界中普通用户运行 Redis 的方式。“在单台机器上运行集群,只是为了能够使用超过 1 个 core" 是额外的复杂性,人们只有在别无选择的情况下才会这样做,如果竞争者无论有多少个 core 都能 “just works",那么最好能有更容易的设置。


还有人表示,这篇文章是 Redis 团队在有礼貌地否认“Dragonfly 是最快的缓存系统”,但更多网友表示,Redis 发文章进行“回击”,就已经代表他们的营销部门输了:


“Redis 投入如此多的工程精力来写这么一篇文章,还对 Reids/Dragonfly 进行了基准测试,这是对 Dragonfly 的极大赞美。”“我很高兴 Redis 发了这篇文章,因此我必须要去了解一下 Dragonfly,它看起来很棒。”

Redis 博客文章翻译:


作为一项基础性技术,每隔段时间总有人跳出来,想要替 Redis 换套新架构。几年之前,KeyDB 就提出了这类方案,而最近亮相的 Dragonfly 则声称是速度最快的 Redis 兼容型内存数据存储系统。没错,这类方案的涌现当然带来了不少值得关注和讨论的有趣技术 / 思路。在 Redis,我们也喜欢迎接挑战,重新审视 Redis 最初的架构设计原则。

 

我们当然一直在寻求为 Redis 提升性能、扩充功能的创新方向,但这里我们想聊聊自己的观点和思考,阐释 Redis 时至今日为何仍是最出色的实时内存数据存储(包括缓存、数据库以及介于二者之间的一切)方案之一。

 

接下来,我们将重点介绍 Redis 对于速度和架构差异的观点,再以此为基础做出比较。在文章的最后,我们还会提供基准测试结果、与 Dragonfly 项目的详尽性能比较信息,欢迎大家自行对比参考。

 

速度问题

Dragonfly 基准测试其实是将独立单进程 Redis 实例(只能使用单一核心)与多线程 Dragonfly 实例(可以使用虚拟机 / 服务器上的全部可用核心)进行比较。很明显,这样的粗暴比较并不能代表 Redis 在现实场景下的运行状态。作为技术构建者,我们希望更确切地把握自有技术同其他方案间的差异,所以这里我们做了一点公平性调整:将具有 40 个分片的 Redis 7.0 集群(可使用其中的大部分实例核心)与 Dragonfly 团队在基准测试中使用的最大实例类型(AWS c4gn.16xlarge)进行性能比较。

 

在这轮测试中,我们看到 Redis 的吞吐量比 Dragonfly 要高出 18% 至 40%,而这还仅仅只用到全部 64 个 vCore 中的 40 个。

 



架构差异

 

背景信息

 

在我们看来,每一位多线程项目的开发者在立项之前,都会根据以往工作中经历过的痛点来指导架构决策。我们也承认,在多核设备上运行单一 Redis 进程(这类设备往往提供几十个核心和数百 GB 内存)确实存在资源无法充分利用的问题。但 Redis 在设计之初也确实没有考虑到这一点,而且众多 Redis 服务商已经拿出了相应的解决方案,借此在市场上占得一席之地。

 

Redis 通过运行多个进程(使用 Redis 集群)实现横向扩展,包括在单一云实例背景下也是如此。在 Redis 公司,我们进一步拓展这个概念并建立起 Redis Enterprise。Redis Enterprise 提供管理层,允许用户大规模运行 Redis,并默认启用高可用性、即时故障转移、数据持久与备份等功能。

 

下面,我们打算分享幕后使用的一些原则,向大家介绍我们如何为 Redis 的生产应用设计良好的工程实践。

 

架构设计原则

 

在每个虚拟机上运行多个 Redis 实例

 

通过在每个虚拟机上运行多个 Redis 实例,我们可以:

  1. 使用一套完全无共享的架构实现纵向与横向线性扩展。与纯纵向扩展的多线程架构相比,这套方案能始终提供更好的架构灵活性。

  2. 提高复制速度,因为复制操作是跨多个进程并发完成的。

  3. 从虚拟机故障中快速恢复。因为新虚拟机的 Redis 实例将同时填充来自多个外部 Redis 实例的数据。

 

将每个 Redis 进程限制为合理的大小

我们不允许单一 Redis 进程的大小超过 25 GB(运行 Redis on Flash 时上限为 50 GB)。如此一来,我们就能:

  • 在出于复制、快照保存、Append Only File(AOF)重写等目的进行 Redis 分叉时,既享受边写边复制的好处,又无需承担繁重的内存开销。若非如此,我们(或客户)将需要支付昂贵的资源成本。

  • 为了轻松管理整个集群,我们希望每个 Redis 实例都保持在较小体量,借此加快迁移分片、重新分片、扩展和重新均衡等的执行速度。

 

横向扩展才是最重要的

以横向扩展的方式灵活运行内存数据存储,是 Redis 获得成功的关键。下面来看具体原因:

  • 更佳弹性——我们在集群中使用的节点越多,整个集群的健壮性就越强。例如,如果您在三节点集群上运行数据集,且其中一个节点发生降级,则代表有三分之一的集群无法运行;但如果是在九节点集群上运行数据集,同样是其中一个节点发生降级,则只有九分之一的集群无法运行。

  • 易于扩展——在横向扩展系统当中,向集群添加一个额外节点、并将数据集的一部分迁移到其中要容易得多。与之对应,在纵向扩展系统中,我们只能直接引入一个更大的节点并复制整个数据集……这是个漫长的过程,而且期间随时有可能闹出麻烦。

  • 逐步扩展更具成本效益——纵向扩展,尤其是云环境下的纵向扩展,往往对应高昂的成本。在多数情况下,即使只需要向数据集内添加几 GB 内容,也需要将实例大小翻倍。

  • 高吞吐——在 Redis,我们看到很多客户会在小型数据集上运行高吞吐量工作负载,即具有极高的网络带宽及 / 或每秒数据包(PPS)需求。我们以每秒操作数 100 万 + 的 1 GB 大小数据集为例,相较于使用单节点 c6gn.16xlarge 集群(128 GB 内存、64 个 CPU 加 100 Gbps 传输带宽,每小时使用成本 2.7684 美元),三个 c6gb.xlarge 节点(8 GB 内存、4 个 CPU 外加最高 25 Gbps 传输带宽,每小时 0.1786 美元)构成的集群能够将运行成本拉低 20%,而且健壮性反而更高。既然成本效益出色、弹性更强且吞吐量反超,那横向扩展无疑就是比纵向扩展更好的选择。

  • 贴近 NUMA 架构——纵向扩展还要求使用能容纳更多核心和大容量 DRAM 的双插槽服务器;相比之下,Redis 这样的多处理架构其实更适应 NUMA 架构,因为其行为特征就接近一种由多个较小节点组成的网络。但必须承认,NUMA 跟多线程架构之间也有天然冲突。根据我们在其他多线程项目中的经验,NUMA 可能令内存数据存储的性能降低达 80%。

  • 存储吞吐量限制——AWS EBS 等外部磁盘的扩展速度,显然不及内存和 CPU。事实上,云服务商会根据所使用设备的类型添加存储吞吐量限制。因此,避免吞吐量限制、满足数据高持久性要求的唯一办法,就是使用横向扩展——即添加更多节点和更多的配套网络附加磁盘。

  • 临时磁盘——临时磁盘是一种将 Redis 运行在 SSD 上的绝佳方式(其中 SSD 用于替代 DRAM,而非充当持久存储介质),能够在保持 Redis 极高速度的同时将数据库成本保持在磁盘级水平。但临时磁盘也有其上限,一旦逼近这一上限,我们还需要进一步扩展容量——这时候,更好的办法仍然是添加更多节点、引入更多临时磁盘。所以,横向扩展继续胜出。

  • 商品硬件——最后,我们的很多客户会在本地数据中心、私有云甚至是小型边缘数据中心内运行 Redis。在这类环境中,绝大多数设备内存不超过 64 GB、CPU 不超过 8 个,所以唯一可行的扩展方式就只有横向扩展。

 

总结

我们仍然欣赏由社区提出的种种有趣思路和技术方案。其中一部分有望在未来进入 Redis(我们已经开始研究 io_uring、更现代的字典、更丰富的线程使用策略等)。但在可预见的未来,我们不会放弃 Redis 所坚守的无共享、多进程等基本架构原则。这种设计不仅具备最佳性能、可扩展性和弹性,同时也能够支持内存内实时数据平台所需要的各类部署架构。

 

附录:Redis 7.0 对 Draonfly 基准测试细节

 

结果概述

版本:

目标:

  • 验证 Dragonfly 公布的结果是否可重现,并确定检索结果的完整条件(鉴于 memtier_benchmark、操作系统版本等信息有所缺失)

  • 确定 AWS c6gn.16xlarge 实例上可实现的最佳 OSS Redis 7.0.0 集群性能,并与 Dragonfly 的基准测试结果相比较

客户端配置:

  • OSS Redis 7.0 解决方案需要大量接入 Redis 集群的开放连接,因为每个 memtier_benchmark 线程都需要连接到所有分片

  • OSS Redis 7.0 解决方案在使用两个 memtier_benchmark 进程时成绩最好,而且为了与 Dragonfly 基准相适应,这两个进程运行在同样的客户端虚拟机上

资源利用与配置优化:

  • OSS Redis 集群在 40 个主分片的配置下性能表现最佳,对应的就是虚拟机上有 24 个备用 vCPU。虽然设备资源仍未得到全部利用,但我们发现继续增加分片数量已经没有意义,反而会拉低整体性能。我们仍在调查具体原因。

  • 另一方面,Dragonfly 解决方案彻底耗尽了虚拟机性能,所有 64 上 vCPU 均达到了 100% 利用率。

  • 在两种解决方案中,我们调整了客户端配置以实现最佳结果。如下所示,我们成功重现了大部分 Dragonfly 基准数据,甚至在 30 通道条件下得出了比项目方更高的测试成绩。

  • 本次测试强调与 Dragonfly 测试环境保持一致,如果调整测试环境,Redis 的成绩还有望进一步提升。

 

最后,我们还发现 Redis 和 Dragonfly 都不受网络每秒数据包或传输带宽的限制。我们已经确认在 2 个虚拟机间(分别作为客户端和服务器,且均使用 c6gn.16xlarge 实例)使用 TCP 传递约 300 B 大小的数据包负载时,可以让每秒数据包传输量达到 1000 万以上、传输带宽超过 30 Gbps。

 

分析结果




单 GET 通道延迟低于 1 毫秒:

  • OSS Redis:每秒 443 万次操作,其中延迟平均值与第 50 百分位值均达到亚毫秒级别。平均客户端延迟为 0.383 毫秒。

  • Dragonfly 声称每秒 400 万次操作:我们成功重现至每秒 380 万次操作,平均客户端延迟为 0.390 毫秒

  • Redis 对 Dragonfly——Redis 吞吐量比 Dragonfly 声称的结果高出 10%,比我们成功重现的 Dragonfly 结果高 18%。

30 条 GET 通道:

  • OSS Redis:每秒 2290 万次操作,客户端平均延迟为 2.239 毫秒

  • Dragonfly 声称每秒可达 1500 万次操作:我们成功重现了每秒 1590 万次操作,客户端平均延迟为 3.99 毫秒

  • Redis 对 Dragonfly——与 Dragonfly 的重现结果和声称结果相比,Redis 分别胜出 43% 和 52%

单 SET 通道延迟低于 1 毫秒:

  • OSS Redis:每秒 474 万次操作,延迟平均值与第 50 百分位值均达到亚毫秒级。客户端平均延迟为 0.391 毫秒

  • Dragonfly 声称每秒 400 万次操作:我们成功重现了每秒 400 万次操作,客户端平均延迟为 0.500 毫秒

  • Redis 对 Dragonfly——与 Dragonfly 的重现结果和声称结果相比,Redis 均胜出 19%

30 条 SET 通道:

  • OSS Redis:每秒 1985 万次操作,客户端平均延迟为 2.879 毫秒

  • Dragonfly 声称每秒 1000 万次操作:我们成功重现了每秒 1400 万次操作,客户端平均延迟为 4.203 毫秒

  • Redis 对 Dragonfly——与 Dragonfly 的重现结果和声称结果相比,Redis 分别胜出 42% 和 99%

用于各变体的 memtier_benchmark 命令:

单 GET 通道延迟低于 1 毫秒

  • Redis:2X: memtier_benchmark –ratio 0:1 -t 24 -c 1 –test-time 180 –distinct-client-seed -d 256 –cluster-mode -s 10.3.1.88 –port 30001 –key-maximum 1000000 –hide-histogram

  • Dragonfly:memtier_benchmark –ratio 0:1 -t 55 -c 30 -n 200000 –distinct-client-seed -d 256 -s 10.3.1.6 –key-maximum 1000000 –hide-histogram

30 条 GET 通道

  • Redis:2X: memtier_benchmark –ratio 0:1 -t 24 -c 1 –test-time 180 –distinct-client-seed -d 256 –cluster-mode -s 10.3.1.88 –port 30001 –key-maximum 1000000 –hide-histogram –pipeline 30

  • Dragonfly:memtier_benchmark –ratio 0:1 -t 55 -c 30 -n 200000 –distinct-client-seed -d 256 -s 10.3.1.6 –key-maximum 1000000 –hide-histogram –pipeline 30

单 SET 通道延迟低于 1 毫秒

  • Redis:2X: memtier_benchmark –ratio 1:0 -t 24 -c 1 –test-time 180 –distinct-client-seed -d 256 –cluster-mode -s 10.3.1.88 –port 30001 –key-maximum 1000000 –hide-histogram

  • Dragonfly:memtier_benchmark –ratio 1:0 -t 55 -c 30 -n 200000 –distinct-client-seed -d 256 -s 10.3.1.6 –key-maximum 1000000 –hide-histogram

30 条 SET 通道

  • Redis:2X: memtier_benchmark –ratio 1:0 -t 24 -c 1 –test-time 180 –distinct-client-seed -d 256 –cluster-mode -s 10.3.1.88 –port 30001 –key-maximum 1000000 –hide-histogram –pipeline 30

  • Dragonfly:memtier_benchmark –ratio 1:0 -t 55 -c 30 -n 200000 –distinct-client-seed -d 256 -s 10.3.1.6 –key-maximum 1000000 –hide-histogram –pipeline 30

 

测试设施细节

在本次比较测试中,我们在客户端(用于运行 memtier_benchmark)和服务器(用于运行 Redis 和 Dragonfly)使用了相同的虚拟机类型,具体规格为:

  • 虚拟机:AWS c6gn.16xlarge

  • aarch64

  • ARM Neoverse-N1

  • 每插槽核心数: 64

  • 每核心线程数: 1

  • NUMA 节点数: 1

  • 核心版本: Arm64 Kernel 5.10

  • 安装内存: 126 GB

 

参考链接:

https://redis.com/blog/redis-architecture-13-years-later/

https://www.reddit.com/r/programming/comments/wiztpx/redis_hits_back_at_dragonfly/


2022-08-10 14:2018100

评论

发布
暂无评论
发现更多内容

Java break、continue 详解与数组深入解析:单维数组和多维数组详细教程

小万哥

Java 程序人生 编程语言 软件工程 后端开发

文心一言 VS 讯飞星火 VS chatgpt (197)-- 算法导论14.3 5题

福大大架构师每日一题

福大大架构师每日一题

【奖项公布】首届全球 TiDB 文档挑战赛圆满收官!来看看前五名花落谁家!

TiDB 社区干货传送门

php作业1

大肚皮狒狒

阿里云-负载均衡(ALB)

智慧源点

ALB

使用 TiKV 读改写 TiDB 数据

TiDB 社区干货传送门

TiDB 源码解读 TiKV 底层架构

听GPT 讲Rust Tokio源代码(7)

fliter

华为音乐用AI送上新年佳曲,花式祝福迎龙年新春

最新动态

华为智慧屏游戏中心合家欢会员免费领!春节团聚畅玩《小小炸弹人》等合家欢游戏

最新动态

考研失败如何快速找到编程工作?

王磊

Java 考研

初识TiDB的增量数据同步工具TiCDC

TiDB 社区干货传送门

迁移 实践案例 7.x 实践

新年新岁,好运 long long

阿里云CloudImagine

云计算 视频云

TiFlash亿级多表关联优化实践,从无法跑出结果优化到2.59秒

TiDB 社区干货传送门

性能调优 实践案例 OLAP 场景实践

听GPT 讲Deno源代码(4)

fliter

数据所在,计算随行:Databend 的 2023 年度总结

Databend

听GPT 讲Rust Tokio源代码(6)

fliter

听GPT 讲Deno源代码(1)

fliter

听GPT 讲Deno源代码(2)

fliter

年青DBA应该学习的数据库之TiDB

TiDB 社区干货传送门

数据库架构设计 数据库前沿趋势

TIKV 分布式事务--乐观事务 2PC 概览

TiDB 社区干货传送门

TiDB 底层架构 TiKV 源码解读

Optimism为 CQT提供价值 20 万美元的生态系统资助,以表彰其支持

股市老人

TiDB 7.5.0 LTS 高性能数据批处理方案

TiDB 社区干货传送门

新版本/特性解读

汽车零部件MES系统实施方案

万界星空科技

汽车 mes 万界星空科技 汽车零部件

听GPT 讲Rust Tokio源代码(8)

fliter

京东零售技术小哥带你揭秘:亿级流量高并发春晚互动前端技术

京东零售技术

前端 春晚

跨越财务困境,聚道云软件连接器如何助力企业轻松实现数字化转型?

聚道云软件连接器

案例分享

TiDB 与MySQL优化器在特定语句下执行效果对比(一)

TiDB 社区干货传送门

性能调优 实践案例 版本测评

听GPT 讲Deno源代码(3)

fliter

TiDB 与MySQL优化器在特定语句下执行效果对比(二)

TiDB 社区干货传送门

性能调优 实践案例 版本测评 新版本/特性发布 6.x 实践

根深叶茂,众行致远 | OpenHarmony项目群技术指导委员会迎新春,展未来

科技热闻

2023年总结

wood

是什么让Redis“气急败坏”回击:13年来,总有人想替Redis换套新架构_开源_赵钰莹_InfoQ精选文章