编程 Valkey 9 源码级深度拆解:原子槽位迁移、哈希字段过期与集群多数据库——一个 Redis 分叉如何跑到 10 亿 QPS

2026-08-01 03:45:46 +0800 CST views 6

Valkey 9 源码级深度拆解:原子槽位迁移、哈希字段过期与集群多数据库——一个 Redis 分叉如何跑到 10 亿 QPS

一句话背景:2024 年 3 月 Redis 把许可证从 BSD 改成 RSALv2 + SSPLv1,社区当天怒而分叉,Linux 基金会接盘,取名 Valkey(女武神)。两年过去,这个「续命项目」已经不是简单的 Redis 平替——Valkey 9.0 带来原子槽位迁移、哈希字段过期、集群模式多数据库,单集群能扩到 2000 节点、跑出每秒超 10 亿次请求。本文从工程第一性原理把这三个杀手锏拆到源码逻辑层,配上运维实战、Go 客户端接入、benchmark 与迁移踩坑清单。

如果你还停留在「Valkey = 换了皮的 Redis 7.2」的印象里,这篇文章大概率会刷新你的认知。作为一个天天跟缓存、分布式锁、消息队列打交道的后端,我把 9.0/9.1 的 release notes、社区讨论和实际压测跑了一遍,越看越觉得:这次分叉不是防守,是进攻。


一、许可证战争:Valkey 到底是怎么来的

先把时间线捋清楚,因为不理解这段历史,就理解不了 Valkey 9 为什么敢在集群架构上大刀阔斧。

  • 2024-03:Redis Labs 把 Redis 从宽松的 3-Clause BSD 切到双许可证——RSALv2(Redis Source Available License)+ SSPLv1(Server Side Public License)。商业使用需授权,云厂商托管 Redis 直接踩线。这一刀砍在了整个开源生态的动脉上。
  • 2024-03(几乎同一周):以 AWS、Google Cloud、Oracle 为首的一批核心贡献者,基于 Redis 7.2.4(最后一个 BSD 版本)拉出分叉,Linux 基金会托管,命名 Valkey。宗旨写死在首页:open source, forever
  • 2024-09:Valkey 8.0 发布,主打多线程 I/O 与性能。
  • 2025-05:Redis 官方「回心转意」,追加 AGPLv3 作为开源选项。但为时已晚——生态已经用脚投票,Valkey 独立演进的势头再也收不回去。
  • 2025 年底:Valkey 9.0 发布,恰好是 8.0 一周年。
  • 2026-05:9.1.0 稳定版;2026-07-21:9.1.1 released(撰文时最新)。

这里有个容易被忽略的关键点:Valkey 现在的协议是 BSD 3-Clause,比 Redis 现在的 AGPLv3 更宽松。 对于要把内存库嵌进商业产品、又不想沾传染性协议的团队来说,Valkey 反而成了「更安全的选择」。Harbor(CNCF 镜像仓库)在 v2.15.2 里就把内部缓存从 Redis 换成了 Valkey,这类迁移案例已经不是个例。

理解了「社区被伤过一次」,你就能理解 Valkey 9 的技术选择:它要证明脱离原厂之后,社区不仅能维护,还能做出原厂没做出来的架构级突破。


二、Valkey 9.0 全景:三大杀手锏 + 一个性能底座

Valkey 9.0 的更新非常克制——没有堆砌一堆花哨命令,而是集中火力解决集群时代的三个「老大难」:

特性解决的历史痛点影响面
原子槽位迁移(atomic slot migration)逐键迁移过程中路由会漂移,扩缩容像拆炸弹集群运维 / 容量规划
哈希字段过期(hash field expiration)Hash 只能整体过期,字段级 TTL 得拆成一堆 key数据建模 / 内存效率
集群模式多数据库(numbered databases in cluster)集群模式下只能用 db0,命名空间隔离无从谈起多租户 / 应用整合

外加一个底座级改动:I/O 线程通信模型用无锁队列重构,配合对现代 CPU 缓存特性的利用,把单集群推到了 2000 节点、10 亿+ QPS 的量级。

下面逐个拆。


三、核心一:原子槽位迁移——扩缩容从「拆炸弹」变成「换轮胎」

3.1 先讲清楚 Redis/Valkey 集群的槽位模型

Valkey 集群把整个 key 空间哈希映射到固定的 16384 个哈希槽(hash slot)。计算方式:

slot = CRC16(key) mod 16384

如果 key 里带了 {...} 花括号(hash tag),只对花括号内的部分做 CRC16,这就是保证多个 key 落到同一槽的手段(事务、Lua、MSET 跨 key 操作依赖它):

user:{1001}:profile   ->  只对 "1001" 算 CRC16
user:{1001}:orders    ->  同一个槽,可以在同一事务里操作

每个节点负责一段或几段槽。扩容 = 把一部分槽从老节点搬到新节点。问题就出在这个「搬」字上。

3.2 旧方式:逐键迁移的三宗罪

9.0 之前,槽迁移是 key 粒度的,大致流程(redis-cli --cluster reshard 底层):

1. 目标节点:  CLUSTER SETSLOT <slot> IMPORTING <src-node-id>
2. 源节点:    CLUSTER SETSLOT <slot> MIGRATING <dst-node-id>
3. 循环:      CLUSTER GETKEYSINSLOT <slot> <count>   # 取一批 key
              MIGRATE <dst-host> <dst-port> "" 0 <timeout> KEYS k1 k2 ...
4. 收尾:      CLUSTER SETSLOT <slot> NODE <dst-node-id>   # 广播归属

在迁移「进行中」这段时间窗口里,槽处于 MIGRATING/IMPORTING 的中间态,客户端访问会收到 ASK 重定向。这带来三个实打实的生产问题:

  1. 路由会漂移:迁移过程中槽归属是「半属于源、半属于目标」,客户端要能正确处理 ASK 重定向,很多老客户端/连接池实现得并不健壮,超时和错误率会飙。
  2. 大 key 阻塞MIGRATE 是同步的,遇到一个几百 MB 的大 Hash/ZSet,单条命令就能把源节点卡住几百毫秒,尾延迟直接爆炸。
  3. 不可预测:迁移耗时取决于 key 数量和大小,没法估工期。凌晨扩容变成了赌博。

一句话总结:旧方式下,扩容不是运维动作,是风险事件。

3.3 新方式:整槽原子迁移 + AOF 流式传输

Valkey 9.0 的原子槽位迁移彻底换了思路——不再按 key 搬,而是一次搬一整个槽,用 AOF 格式做原子移动。

核心机制(结合社区设计文档梳理):

  • 源节点为待迁移的槽生成一份 AOF 格式的数据流(等价于把这个槽的所有写操作重放序列),通过复制通道推给目标节点。
  • 迁移期间源节点继续对外服务,新产生的写入以「增量 AOF」形式续传,类似主从全量+增量同步。
  • 当目标节点追平后,做一次原子归属切换:槽的所有权在一个明确的、不可分割的时间点从源交给目标。切换前所有请求走源,切换后所有请求走目标,不存在「半迁移」的中间态

对比一下心智模型:

旧方式(逐键):       换轮胎时先把螺丝一个个卸下来,卸一半车还在开
新方式(原子整槽):   千斤顶顶起、整个轮子一次换好、放下,切换只在落地那一瞬

带来的直接收益:

  • 键路由一致性:客户端要么看到旧归属、要么看到新归属,不会看到中间态,ASK 重定向风暴消失。
  • 可预测的交接:切换是一个点事件,扩容工期能估算了。Momento 的工程师直接点评:「这从根本上改变了容量规划和运维风险管理方式——扩容将变得可预测,而不再是痛苦的过程。」
  • 减少过渡性错误:在线重分片(online resharding)真正做到了「在线」。

3.4 运维实战

启动原子迁移(命令形态以 9.0+ 为准,具体子命令请以 CLUSTER HELP 和官方文档为准):

# 传统交互式 reshard 仍可用,但底层已走原子迁移路径
redis-cli --cluster reshard 127.0.0.1:7000 \
  --cluster-from <src-node-id> \
  --cluster-to   <dst-node-id> \
  --cluster-slots 1000 \
  --cluster-yes

# 观察迁移进度:关注这几个指标
redis-cli -p 7000 CLUSTER INFO        # cluster_state / cluster_slots_assigned
redis-cli -p 7000 INFO replication    # 迁移通道的同步进度
redis-cli -p 7000 CLUSTER SLOTS       # 实时槽归属

踩坑提示

  • 原子迁移吃的是复制带宽 + 目标节点的内存写入能力。搬一个装满数据的槽,本质是一次「定向全量同步」,务必在低峰期做,并监控目标节点 used_memory 和网卡。
  • 9.1 新增了 cluster bus 网络流量指标(bytes 级),迁移期间可以精确观测集群总线开销,别再靠网卡总流量瞎猜了。

四、核心二:哈希字段过期——被等了十年的特性

4.1 为什么这个特性这么难产

Redis/Valkey 的 Hash 是最常用的结构之一:存用户资料、存对象、存计数器分桶。但在 9.0 之前,TTL 只能设在 key 级别,不能设在 Hash 内部的字段级别。

这意味着一个经典场景直接被卡死:

我想存用户的会话属性,session:{uid} 是一个 Hash,里面 token 30 分钟过期、last_active 永不过期、captcha 60 秒过期——三个字段三种寿命。

9.0 之前你只能选两条烂路:

  1. 拆成多个独立 keysession:{uid}:tokensession:{uid}:captcha……Hash 的聚合优势荡然无存,key 数量爆炸,内存元数据开销剧增。
  2. 应用层自己扫过期:在字段里塞一个过期时间戳,读的时候判断,写个定时任务清理。又累又容易出 bug。

为什么官方一直不做?因为实现起来是内核级的硬骨头:Hash 的底层编码(listpack / hashtable)本身不带每字段元数据,要加字段级 TTL,等于要给每个 field 挂一个到期时间,还要有一套高效的「主动过期」机制去回收,同时不能把内存开销和吞吐打下来。

4.2 Valkey 9.0 的实现:主动过期 + 可控内存开销

Valkey 9.0 实现了字段级过期,关键设计点:

  • 每字段独立 TTL:Hash 内每个 field 可以有自己的到期时间,互不影响。
  • 主动过期(active expiration)机制:Valkey 用一个共享的主动过期任务周期性扫描并回收已过期的哈希字段,而不是纯靠「访问时惰性删除」。这保证了即使某些字段再也不被访问,内存也能被及时回收。
  • 实测代价可控:AWS 工程师给出的基准结论是——字段级过期在不牺牲内存效率或延迟的前提下加入,额外内存开销保持可控,指令吞吐未受影响,共享主动过期任务在高写入压力下仍能高效回收内存。

4.3 命令实战

字段级过期沿用了业界已经形成事实标准的 HEXPIRE 命令家族(与 Redis 7.4 引入的语义保持兼容,便于生态迁移;具体以你所用版本的 COMMAND DOCS 为准):

# 建一个会话 Hash
HSET session:1001 token "abc123" last_active "1730000000" captcha "8848"

# 给 token 设 30 分钟(1800 秒)过期
HEXPIRE session:1001 1800 FIELDS 1 token
# -> 返回 1 表示设置成功

# 给 captcha 设 60 秒过期
HEXPIRE session:1001 60 FIELDS 1 captcha

# 一次给多个字段设过期
HEXPIRE session:1001 300 FIELDS 2 token captcha

# 查看字段剩余 TTL(秒)
HTTL session:1001 FIELDS 2 token captcha
# -> 1) (integer) 1790
#    2) (integer) 55

# 毫秒级
HPEXPIRE session:1001 90000 FIELDS 1 token
HPTTL   session:1001 FIELDS 1 token

# 用绝对时间戳
HEXPIREAT  session:1001 1730003600 FIELDS 1 token
HPEXPIREAT session:1001 1730003600000 FIELDS 1 token

# 查到期的绝对时间点
HEXPIRETIME session:1001 FIELDS 1 token

# 取消某字段的过期(转永久)
HPERSIST session:1001 FIELDS 1 last_active

HEXPIRE 的返回码语义很重要,生产代码里要处理全套:

  • 2:字段因为 TTL <= 0(或已过期)被直接删除
  • 1:过期设置成功
  • 0:因为条件不满足(NX/XX/GT/LT)没设置
  • -2:字段不存在,或 key 不存在

带条件设置(避免覆盖已有更长的 TTL):

# 只在字段当前没有 TTL 时才设置(NX)
HEXPIRE session:1001 1800 NX FIELDS 1 token
# 只在新 TTL 比现有更大时才更新(GT)——防止把长效 token 误缩短
HEXPIRE session:1001 3600 GT FIELDS 1 token

4.4 一个真实建模收益

拿购物车举例,改造前后对比:

# 改造前:一个购物车拆成 N 个 key,还要额外维护一个 set 记录成员
cart:{uid}:item:sku1   TTL 24h
cart:{uid}:item:sku2   TTL 12h   # 限时商品
cart:{uid}:items       (set)     # 为了能遍历

# 改造后:一个 Hash 搞定,字段各自过期,遍历天然支持
HSET   cart:{uid} sku1 2 sku2 1
HEXPIRE cart:{uid} 86400 FIELDS 1 sku1
HEXPIRE cart:{uid} 43200 FIELDS 1 sku2   # 限时商品自动掉
HGETALL cart:{uid}                        # 一次拿全,过期的自动不在

key 数量从 O(商品数) 降到 O(1),内存里省掉的是每个独立 key 的 dict entry、expire dict entry、robj 头等一堆元数据。缓存密集型业务上,这个差距能到 30%~50% 的内存节省。


五、核心三:集群模式多数据库——迟到的命名空间

5.1 历史限制

单机 Redis/Valkey 一直有 16 个编号数据库(db0~db15),用 SELECT n 切换。它常被当作轻量级命名空间:把不同业务、不同租户的数据隔开,避免 key 冲突。

集群模式下,只能用 db0。这是 Redis 时代就有的限制——因为槽位路由、跨库操作、复制语义在多库 + 分片叠加时会变得非常复杂。于是所有人只能在集群里靠 key 前缀(app1:tenantA:)自己模拟命名空间。

5.2 Valkey 9.0 解锁多数据库集群

9.0 取消了这个限制,引入集群模式下对编号数据库的完整支持。Valkey 开源负责人 Kyle Davis 把编号数据库定位成一种命名空间机制,最直接的用途是:

需要逻辑上隔离数据、同时能接受资源共享的场景。比如把不同客户的数据分隔开,或在资源不成问题时把多个应用整合进同一个集群。

# 集群模式下现在可以正常 SELECT
redis-cli -c -p 7000
127.0.0.1:7000> SELECT 3
OK
127.0.0.1:7000[3]> SET tenantA:key1 "v"

5.3 使用边界(别踩坑)

多数据库不是银弹,用之前想清楚三件事:

  1. 它是逻辑隔离,不是资源隔离。db3 和 db0 共享同一批节点的 CPU、内存、网卡。一个库把内存打满,所有库一起 OOM。真要资源隔离,还是得上多集群。
  2. 跨库操作依然受限。事务、Lua、多 key 命令仍然要求 key 在同一槽;跨 db 的原子操作不要指望。
  3. 它替代不了 key 前缀的可观测性。前缀方案至少能用 SCAN MATCH app1:* 粗略统计;多 db 的按库统计工具链目前还没那么成熟。我的建议:多租户强隔离用集群/前缀,多 db 用于「同一业务的逻辑分区」(比如 db0 主数据、db1 临时计算区)。

六、性能底座:无锁 I/O 队列与 2000 节点

三大特性之外,9.x 真正的「内功」在于 I/O 与并发模型的重构。

6.1 I/O 线程通信重构为无锁队列

Valkey 8.0 已经引入了多线程 I/O(把 socket 读写、命令解析、回包序列化交给 I/O 线程,主线程只跑命令执行)。9.1-rc 阶段进一步重新设计了 I/O 线程通信模型,改用 lock-free queue(无锁队列)

为什么这事重要?多线程 Redis/Valkey 的经典瓶颈从来不是「算得慢」,而是主线程和 I/O 线程之间的同步开销。旧模型里线程间交接任务要过锁/条件变量,高并发下锁竞争把多核优势吃掉一大半。无锁队列(通常是基于 CAS 的 MPSC/SPSC ring buffer)把交接路径变成原子操作,减少上下文切换和 cache line 争用,尾延迟(p99/p999)明显收窄。

6.2 「智能利用现代 CPU」到底指什么

社区反复强调 9.0 的性能来自「对现代 CPU 能力的智能利用」。落到实处主要是三块:

  • 数据结构与访问模式的 cache 友好化:减少指针跳转、提升局部性,让热点数据尽量待在 L1/L2。
  • 减少伪共享(false sharing):把被不同线程频繁写的字段做 cache line 对齐/隔离。
  • 无锁化关键路径:如上文的 I/O 队列。

结果就是官方给出的三个可量化收益:更低的尾延迟、更高的单节点吞吐、可量化的成本效率(同样 QPS 需要更少的机器)

6.3 2000 节点 / 10 亿 QPS 的含义

社区讨论展示 9.0 能扩展到 2000 个节点、每秒超 10 亿次请求。别被数字唬住,理解它的前提:

  • 这是水平扩展的能力上限,靠的是集群总线(cluster bus,gossip 协议)在大规模下的稳定性改进——节点越多,gossip 心跳、槽位广播、故障检测的开销越大,2000 节点意味着 gossip 层做了实打实的优化。
  • 10 亿 QPS 是整个集群聚合的数字,不是单节点。单节点在现代硬件上多线程模式能到几十万到百万级 QPS(取决于命令、pipeline、value 大小)。
  • 9.1 加的 cluster bus 流量指标(bytes) 正是为了让你在大集群里能观测总线成本——节点规模上去后,gossip 流量可能成为隐形瓶颈。

七、9.1 增量:安全、可观测性与「AI 修 bug」

9.1(2026-05 稳定,9.1.1 于 2026-07-21)是一次务实的迭代:

7.1 三个必须打的安全补丁

生产环境如果还在 9.0 或更低,尽快升级——9.1 修了三个内存安全 CVE:

  • CVE-2026-23479:unblock client 流程中的 Use-After-Free
  • CVE-2026-25243RESTORE 命令的非法内存访问
  • CVE-2026-23631:full sync 期间遇到 yielding 的 Lua/function 执行时的 use-after-free

三个都是内存破坏类,理论上有 RCE/DoS 风险,别拖。

7.2 可观测性与延迟优化

  • cluster bus 网络流量指标(bytes)(#3396):大集群的总线开销终于可观测。
  • rehashing 期间增量页释放降低延迟毛刺(#3481):Hash/dict 扩容 rehash 时,旧表内存不再一次性释放,改为增量释放,消除了 rehash 尾期的延迟尖刺。
  • replica 最优排名时立即 failover:故障切换更果断,减少不必要的等待窗口。
  • Lua 脚本引擎默认静态链接:减少动态链接开销与部署依赖。
  • 延迟观测层面,Valkey 集成了 HDR Histogram 做命令延迟分布跟踪,配合 latency-monitor-thresholdLATENCY HISTORY / LATENCY GRAPH,定位慢命令比看平均值靠谱得多。

7.3 有意思的花絮:一批 bug 由 AI 智能体修复

9.1 里有相当一部分 bug 修复工作是由 AI 智能体完成的。这不是噱头——对一个成熟 C 项目来说,AI Agent 在「定位内存越界、补 NULL 检查、修资源泄漏」这类模式化 bug 上确实能提效。9.1 的 bug 修复列表里能看到不少这类补丁,比如 syncRead 的 EOF errno 传播、GEOSEARCH BYPOLYGON 的内存泄漏、streamTrim 的 NULL 指针处理。这也侧面说明社区在拥抱 AI 辅助的工程化实践。


八、上手实战:部署、Go 接入、压测、监控

8.1 部署

# Docker(最快)
docker run -d --name valkey -p 6379:6379 valkey/valkey:9.1.1

# macOS
brew install valkey && brew services start valkey

# Ubuntu/Debian
sudo apt update && sudo apt install valkey -y
sudo systemctl enable --now valkey-server

# 源码编译(要 TLS 就带上 BUILD_TLS)
git clone https://github.com/valkey-io/valkey.git
cd valkey && make BUILD_TLS=yes -j$(nproc) && sudo make install

valkey-cli ping   # -> PONG

关键配置(valkey.conf)片段,缓存场景推荐:

maxmemory 4gb
maxmemory-policy allkeys-lru      # 纯缓存用 lru;有持久化需求用 volatile-*
io-threads 6                      # 多核机器打开多线程 I/O,别超过物理核数
appendonly yes                    # 需要持久化时开 AOF
appendfsync everysec              # 吞吐/安全的平衡点
latency-monitor-threshold 10      # 记录 >10ms 的命令,配合 LATENCY 排查

8.2 Go 客户端接入(go-redis 兼容 Valkey)

Valkey 完全兼容 RESP 协议和 Redis 客户端,go-redis 直接用:

package main

import (
	"context"
	"fmt"
	"time"

	"github.com/redis/go-redis/v9"
)

func main() {
	ctx := context.Background()

	// 单机
	rdb := redis.NewClient(&redis.Options{
		Addr:         "127.0.0.1:6379",
		PoolSize:     50,
		MinIdleConns: 10,
		ReadTimeout:  200 * time.Millisecond,
	})

	// 写入 Hash 并设置字段级过期
	key := "session:1001"
	rdb.HSet(ctx, key, "token", "abc123", "last_active", time.Now().Unix())

	// go-redis v9 支持 HExpire 家族
	res, err := rdb.HExpire(ctx, key, 30*time.Minute, "token").Result()
	if err != nil {
		panic(err)
	}
	fmt.Println("HEXPIRE result:", res) // [1]

	ttl, _ := rdb.HTTL(ctx, key, "token").Result()
	fmt.Println("token TTL:", ttl) // [1799]
}

集群模式客户端:

rdb := redis.NewClusterClient(&redis.ClusterOptions{
	Addrs:        []string{"127.0.0.1:7000", "127.0.0.1:7001", "127.0.0.1:7002"},
	RouteRandomly: true,      // 只读命令分散到副本
	PoolSize:     100,
})
// 原子槽位迁移让 MOVED/ASK 重定向大幅减少,
// 但客户端仍需保留重定向处理能力(连接池/拓扑刷新)。

8.3 压测

# 基础:默认 15 种命令
valkey-benchmark -h 127.0.0.1 -p 6379

# 贴近真实负载:50 并发、100w 请求、1KB value、只测 set/get、随机 key
valkey-benchmark -c 50 -n 1000000 -d 1024 -t set,get -r 100000

# pipeline 压吞吐(-P 16 表示每次批 16 条)
valkey-benchmark -c 50 -n 1000000 -P 16 -t set,get

压测经验:单看 ops/sec 没意义,一定要盯 p99/p999 延迟。多线程 I/O(io-threads)在小包高并发场景收益最大;大 value 场景瓶颈在网卡和内存带宽,加线程无用。

8.4 监控要点

# 延迟分布
valkey-cli LATENCY HISTORY command
valkey-cli LATENCY RESET

# 内存
valkey-cli INFO memory | grep -E "used_memory:|mem_fragmentation_ratio"

# 集群总线流量(9.1 新指标)
valkey-cli INFO stats | grep cluster

重点盯三个指标:mem_fragmentation_ratio(>1.5 考虑重启/整理)、evicted_keys(持续增长说明内存不够)、instantaneous_ops_per_sec(吞吐基线)。


九、从 Redis 迁移到 Valkey 的踩坑清单

Valkey 号称「drop-in replacement」,实际迁移我踩过的坑:

  1. 协议兼容但版本特性不完全对齐。Valkey 从 Redis 7.2 分叉,Redis 7.4+ 的部分特性 Valkey 用自己的实现补齐(比如哈希字段过期)。命令名和语义大体兼容,但别假设 100% 一致,上线前用 COMMAND DOCS 核对你依赖的命令
  2. 持久化文件格式。RDB/AOF 在 7.2 分叉点之后各自演进,跨产品直接拷贝 dump 文件有风险。稳妥做法是用 replicaof 让 Valkey 作为 Redis 的副本做全量同步,追平后再切主。
  3. 客户端库。绝大多数 Redis 客户端直接可用(RESP2/RESP3 兼容),但一些强依赖 Redis 特有模块(RedisJSON、RediSearch 等闭源模块)的场景,Valkey 侧要换成社区对应模块,不能无脑迁。
  4. 集群拓扑刷新。启用原子槽位迁移后重定向变少了,但客户端的集群拓扑自动刷新仍要保留——扩缩容后节点归属会变。
  5. 监控/告警适配。指标名基本一致,但 9.1 新增了 cluster bus bytes 等指标,告警规则记得补上。

迁移最小方案:Valkey 挂成 Redis 的 replica → 观察同步完成 → 灰度切读 → 切写 → 摘除 Redis。全程可回滚。


十、选型建议与总结

什么时候选 Valkey 9

  • 在意许可证:要把内存库嵌进商业产品、又不想碰 AGPLv3 的传染性——Valkey 的 BSD 3-Clause 是当前最省心的选择。
  • 大规模集群:节点数上百、要频繁扩缩容——原子槽位迁移和 gossip 优化就是为你准备的。
  • 缓存内存敏感:大量 Hash 存对象 + 字段级 TTL 需求——哈希字段过期能实打实省内存、省 key。
  • 多租户/多应用整合:需要轻量逻辑隔离——集群多数据库能用了。

什么时候可以再等等

  • 深度绑定 Redis 闭源模块(RediSearch/RedisJSON/RedisTimeSeries 的商业特性)的存量系统,迁移成本要单独评估。
  • 对「原厂背书」有合规硬要求的保守型组织。

一句话总结

Valkey 9 已经完成了从「Redis 平替」到「独立进化体」的身份转变。原子槽位迁移解决了集群运维的最大痛点,哈希字段过期补齐了等了十年的建模短板,集群多数据库打开了多租户的门,而无锁 I/O 底座让这一切跑在 10 亿 QPS 的量级上。对我这种天天跟缓存打交道的后端来说,结论很直接:新项目直接上 Valkey 9.1.1,存量 Redis 排期评估迁移。 一个被伤过的社区,用两年时间证明了——开源的生命力,从来不在某一家公司手里。


参考:Valkey 官方(valkey.io)9.0/9.1 release notes、Linux Foundation 发布公告、InfoQ 相关报道、Valkey GitHub releases(9.1.0 / 9.1.0-rc2 / 9.1.1)。文中命令语法请以你所用版本的 COMMAND DOCS / 官方文档为准。

推荐文章

阿里云免sdk发送短信代码
2025-01-01 12:22:14 +0800 CST
底部导航栏
2024-11-19 01:12:32 +0800 CST
虚拟DOM渲染器的内部机制
2024-11-19 06:49:23 +0800 CST
Go 接口:从入门到精通
2024-11-18 07:10:00 +0800 CST
Nginx 跨域处理配置
2024-11-18 16:51:51 +0800 CST
Elasticsearch 条件查询
2024-11-19 06:50:24 +0800 CST
程序员茄子在线接单