Redis vs Valkey 深度对决:许可风波后,谁才是内存数据库的未来之选

470 阅读9分钟

大家好,这里是小奏,觉得文章不错可以关注公众号小奏技术

背景

2024-2025Redis 的两次重大许可变更

不仅撕裂了社区,更催生了Valkey这个强劲对手。

当硝烟散去,超越许可之争,Redis 8.0Valkey 8.1 在性能、架构、功能上究竟孰强孰弱?

RedisValkey我们应该选用谁呢?

架构:核心数据处理与网络 I/O

线程架构对内存数据存储的延迟、吞吐量、可扩展性和资源利用率有着关键影响。

虽然单线程简化了并发控制,但多线程能够释放现代硬件的潜力,使得线程模型成为高吞吐量应用程序的关键差异化因素。

Redis 和 Valkey 都在演进各自方法的同时平衡着这些权衡。

Redis 的新 I/O 线程实现

Redis 通过其著名的单线程命令执行和数据处理保持了简单性,确保了原子性,同时避免了争用、锁和上下文切换。

然而,自 6.0 版本以来,Redis 已纳入多线程 I/O 以提升性能:

redis.io/blog/diving…

  • 通过将读写 I/O 套接字所花费的时间委托给其他线程,Redis 进程可以将更多周期投入到操作、存储和检索数据上。

虽然这是一个重大的进步,但最初的实现并未完全实现性能潜力。

Redis 8.0 通过改进的新 I/O 线程模型解决了这个问题,该模型提供了显著更好的吞吐量:

redis.io/blog/redis-…

  • 在多核 Intel CPU 上将 io-threads 参数设置为 8 时,我们测量到吞吐量提升了高达 112%。

Valkey 的异步 I/O 线程

作为 Redis 的分支,Valkey 保留了相同的单线程核心用于命令处理以保持原子性。然而,Valkey 8.0 引入了增强的异步 I/O 线程,

valkey.io/blog/valkey…

允许并发处理网络读/写,同时保持数据处理为单线程。

此外,Valkey 能够根据实时使用情况智能地将 I/O 任务分配到多个核心上,从而提高了整体硬件利用率。

性能特征

Valkey 和 Redis 中的最新 I/O 线程实现都带来了显著的吞吐量改进,尽管它们的性能特征因硬件和工作负载而异。

在 AWS c7g.4xlarge 实例(Graviton3,16 vCPU)上进行基准测试时

Valkey 8.0 表现出了特别令人印象深刻的增益,达到了每秒 119 万次请求(RPS)——比 Valkey 7.2 的 36 万 RPS 提高了 230%。

Valkey 8.0 vs. Valkey 7.2 | 吞吐量和延迟对比

Momento 最近在 AWS c8g.2xlarge 实例(Graviton4,8 vCPU)上进行的一项更全面的测试显示

无论是 Valkey 8.1 还是 Redis 8.0 都无法持续达到 100 万 RPS。

然而,在这个更小但更新一代的 CPU 配置上,两者都惊人地接近 73 万至 100 万 RPS 的范围。

这些基准测试共同表明,虽然两种数据存储都显著受益于现代线程方法

但 Valkey 的实现目前在多核系统上显示出更大的扩展空间。下表总结了上面讨论的最新基准测试结果。

请注意,详细的基准测试配置请参考原始文章。

指标Valkey 8.0 (c7g.4xl)Valkey 8.1 (c8g.2xl)Redis 8.0 (c8g.2xl)
吞吐量 (RPS)1.19MGET: 947.1K, SET: 999.8KGET: 821.4K, SET: 729.4K
平均延迟 (ms)0.542GET: 0.21, SET: 0.352GET: 0.44, SET: 0.51
P99 延迟 (ms)0.927GET: 0.28, SET: 0.80GET: 0.95, SET: 0.99

关键限制

尽管在 I/O 线程方面有所改进

但 Redis 和 Valkey 在消耗大部分 CPU 周期的核心工作负载——数据处理方面,本质上仍然是单线程的。

这种架构选择保留了原子性,但也带来了固有的瓶颈:

  • 增加核心数提高了 I/O 吞吐量,但并未加速实际的命令执行,这限制了垂直扩展能力。

  • CPU 密集型工作负载(例如,复杂的 Lua 脚本、有序集合操作)仍然会阻塞主线程,导致延迟尖峰甚至服务器无响应。

持久化与后台操作

除了网络 I/O 和命令处理,Redis 和 Valkey 都利用 fork 进程进行必要的后台操作

特别是与持久化、维护和高可用性相关的操作,尽管它们的实现在某些方面有所不同。

Redis 基于 Fork 的操作

Redis 采用基于 fork() 的后台处理来实现关键功能。

  • RDB(Redis 数据库)快照:提供时间点备份用于灾难恢复。

  • AOF(仅追加文件):记录服务器接收的每个写操作,这些操作可以在服务器启动时重放,重建原始数据集。

  • AOF 重写:一种通过删除同一键上的过时写入来维护日志压缩的机制。

  • 复制:对高可用性设置非常有用。

许多这些机制策略性地使用 fork() 来防止 Redis 服务器阻塞,优先保证维护操作期间的服务连续性。

  • RDB 快照:在后台创建快照时(通过 BGSAVE 或自动触发),Redis 会 fork 一个子进程将 RDB 文件写入磁盘。虽然这保持了主进程的响应性,但在写入密集的实例上可能会触发显著的写时复制(Copy-On-Write, COW)内存开销,因为内核会复制被修改的内存页。

  • AOF 重写:对于日志压缩(通过 BGREWRITEAOF 或自动触发),子进程会生成一个优化的 AOF 文件。与 RDB 类似,这避免了阻塞,但在高写入活动期间遭受相同的 COW 代价。

  • 复制:在与副本进行初始完全同步期间,主节点会 fork 以创建用于传输的 RDB 快照。在 RDB 快照创建并传输到副本后,主实例开始在完全同步期间流式传输额外的写命令。

最近的 Redis 版本增强了这些机制。

Redis 7.0 引入了多部分 AOF(multi-part AOF)以减少 AOF 重写开销

而 Redis 8.0 通过使用两个并行流改进了复制:一个用于传输 RDB 快照,另一个用于传输实时更改。

Redis 8.0 | 双流复制

Valkey 的增强

虽然保留了相同的基于 fork() 的核心机制用于 RDB 快照和 AOF 重写操作

但 Valkey 8.0 引入了一种显著改进同步的双通道复制方案。

值得注意的是,尽管类似,但 Valkey 实现此机制的时间远早于 Redis 8.0。

这一增强允许 Valkey 在完全同步期间同时流式传输 RDB 快照和复制积压(replication backlog)。

它还使用专用连接进行 RDB 传输,释放主进程专注于处理客户端查询。

关键限制

尽管进行了优化,但两个系统仍然存在一些固有的挑战:

  • Fork 开销:写入密集的工作负载在 RDB 快照或 AOF 重写期间仍然频繁触发昂贵的写时复制内存复制,存在临时性能下降的风险。

  • 内存扩展:大型数据集上的写入密集工作负载需要显著的开销(额外 25-50% 的 RAM)以避免 OOM(内存不足)终止。

  • 延迟敏感性:主进程在 fork() 期间会短暂阻塞,这对于亚毫秒级用例可能很重要。

  • 调优依赖性:最佳行为需要仔细配置持久化和复制设置。

对于内存受限或延迟关键的部署,这些限制仍然不容忽视。

功能集与数据结构

Redis 和 Valkey 都支持用于丰富数据类型

(包括字符串、位图、列表、哈希、集合、有序集合、流、地理空间索引、HyperLogLog 和 Pub/Sub)数据操作的众多命令。

它们也都支持通过 Lua 脚本进行可编程性。

Redis 8.0 利用其成熟的 API,并将原始的 Redis Stack 模块打包到一个发行版中,以针对高级用例:

  • 它将概率数据结构(即布隆过滤器、布谷鸟过滤器)、JSON、时间序列和搜索功能直接捆绑到核心中。

  • 向量集合(Vector set),一种新的原生类型,支持高维相似性搜索——这对于推荐系统和语义搜索等 AI 工作负载至关重要。

Valkey 则优先考虑核心优化,同时也在逐步添加新的数据类型和命令:

  • 截至 Valkey 8.1,它已经支持 JSON 和布隆过滤器数据类型及相关命令。

  • 它还实现了一种新的 CPU 缓存友好的哈希表,每个键值对可减少约 20 字节的内存。当包含大量元素时,嵌套数据类型(哈希、集合、有序集合)每个元素也能节省 10-20 字节。

不同值大小下的 Valkey 内存开销 | 越低越好

权衡取舍

  • Redis 8.0 的集成模块和原生向量集合使其成为 AI 驱动和高级分析工作负载的更强选择,为语义搜索、时间序列数据和 JSON 文档存储提供了开箱即用的解决方案——所有这些都与核心引擎紧密耦合。

  • Valkey,虽然目前缺乏某些数据类型和搜索功能,但通过其重新设计的哈希表等基础优化进行了弥补,这带来了可衡量的内存节省。这使得 Valkey 对于传统的缓存、队列和高吞吐量场景特别有吸引力,在这些场景中,原始效率胜过专业功能。

许可协议

从 Redis 8.0 开始,Redis 采用了三许可证模式,提供三种选择:

  • Redis 源代码可用许可证 v2 (RSALv2)

  • 服务器端公共许可证 v1 (SSPLv1)

  • GNU Affero 通用公共许可证 v3 (AGPLv3)。

虽然包含 AGPLv3 恢复了其开源分类,但此举仍面临质疑。

由于其严格的要求,组织通常对采用 AGPLv3 犹豫不决,而且 2024 年的许可变更已经撕裂了部分社区信任。

三种许可证的复杂性也为优先考虑简洁性而非法律细则的开发者带来了摩擦。

Valkey 则相反,使用简单明了的 BSD 3-Clause 许可证

这是一种宽松的、广为人知的选择,符合主流开源预期。

这种简洁性降低了采用门槛,并安抚了那些对许可风险持谨慎态度的用户。

最终抉择:没有最好,只有最合适

Redis 和 Valkey 之间的选择最终取决于您的优先事项。

  • 如果您需要向量搜索、JSON 支持和 AI 就绪性等高级功能,Redis 8.0 仍然是更强的选择——尽管其许可模式复杂。

  • 然而,如果您看重简洁性、内存效率和宽松的开源许可证,Valkey 的流线型架构和 BSD 许可使其成为一个有吸引力的替代方案,尤其适用于传统的缓存和高吞吐量工作负载。

参考