编程 Valkey 9.0 深度实战:当开源社区重塑内存数据库——从异步 IO 到原子槽位迁移的生产级完全指南(2026)

2026-06-06 00:06:38 +0800 CST views 7

Valkey 9.0 深度实战:当开源社区重塑内存数据库——从异步 IO 到原子槽位迁移的生产级完全指南(2026)

2024 年 Redis 换证风暴后,Valkey 从 Redis 7.2.4 分叉而出。两年后的今天,Valkey 已经发展到 9.0 大版本——25.4k GitHub Stars、2000 节点集群、单节点 120 万 QPS、集群 10 亿 RPS。它不再是一个「Redis 替代品」,而是用自己的架构重新定义了内存数据库这个品类。

一、背景:一场由许可证引发的开源革命

1.1 Redis 换证事件始末

2024 年 3 月,Redis Labs(后更名为 Redis Inc.)宣布将 Redis 核心代码的许可证从 BSD 变更为 RSALv2(Redis Source Available License v2)和 SSPL v1 双许可证模式。这意味着:

  • 云厂商(AWS、Google Cloud、Oracle 等)不能再将 Redis 作为托管服务提供给客户
  • 任何修改后的版本也不能作为云服务提供
  • 许可证从「真正的开源」变成了「源代码可用」

这一决定在开源社区引发了巨大震动。Redis 作为全球使用最广泛的内存数据库,支撑着数百万应用的生产环境。许可证变更直接威胁到了整个云原生生态的自由度。

1.2 Valkey 的诞生

仅仅 8 天之后,Linux 基金会联合 AWS、Google Cloud、Oracle、Snap 等多家科技公司宣布支持 Valkey 项目。Valkey 基于 Redis 7.2.4(BSD 许可证下的最后一个稳定版本)分叉,在 Linux 基金会托管下继续以 BSD 3-Clause 许可证开源。

2024 年 4 月 16 日,Valkey 在北美开源峰会(Open Source Summit North America 2024)上正式发布首个版本 7.2.5 RC。从分叉到发布,仅用了 3 周。

1.3 版本演进时间线

版本发布时间核心突破
7.2.5 RC2024 年 4 月分叉首个版本,兼容 Redis 7.2.4
8.0 GA2024 年 9 月异步 IO 线程、数据预取、MAA,单节点 100-120 万 QPS
9.0 GA2025 年 12 月原子槽位迁移、多数据库集群、哈希字段过期,集群 10 亿 RPS

1.4 最新动态:Redis 重新开源

值得注意的是,Redis 项目创始人 antirez 在 2025 年加入 Redis Inc. 后,Redis 宣布从 Redis 8 开始重新开源。但 Valkey 已经在这两年间建立了自己的技术路线和社区生态,两者将长期共存竞争。

二、Valkey 8.0 架构革命:异步 IO 线程

2.1 Redis 6.0 多线程 IO 的局限

在理解 Valkey 的突破之前,先回顾 Redis 6.0 的多线程 IO:

Redis 6.0 引入了多线程 IO 来处理网络数据的读写和协议解析,但存在明显问题:

  1. 同步等待模型:主线程将所有可读客户端加入队列后,需要等待所有 IO 线程完成读写操作
  2. IO 线程利用率低:主线程处理命令时,IO 线程全部空闲;主线程执行 IO 任务时,又受最慢线程拖累
  3. 任务范围窄:IO 线程仅执行读取解析和写入操作,命令查找等仍然在主线程

这使得 Redis 6.0 将单节点 QPS 从 10 万提升到约 20 万,但天花板明显。

2.2 Valkey 8.0 的异步 IO 架构

Valkey 8.0 彻底重构了 IO 模型,核心变化是从同步等待变为异步任务队列

Redis 6.0 流程:
主线程收集事件 → 暂停 → 唤醒所有IO线程 → 等待全部完成 → 处理命令
(IO线程在主线程收集/等待期间全部空闲)

Valkey 8.0 流程:
主线程监测事件 → 立即派发到任务队列 → IO线程异步执行
(主线程和IO线程并行工作,无阻塞等待)

环形缓冲区任务队列

Valkey 在启动时为每个 IO 线程创建一个静态、无锁、固定大小(2048)的环形缓冲区作为任务队列。主线程通过环形缓冲区向 IO 线程发送任务,IO 线程异步从中获取任务执行。

为什么用环形缓冲区?

  • 无锁设计避免了锁竞争的开销
  • 固定大小保证内存预分配,无动态分配延迟
  • 单向通道(主线程 → IO 线程)简化了并发控制

读数据流程

// Valkey 8.0 读数据流程(简化)
// 1. 主线程检测到可读事件
while ((nread = read(fd, buf, sizeof(buf))) > 0) {
    // 2. 如果开启IO线程,将读任务派发到任务队列
    if (io_threads_active) {
        iothread_post_read(client);  // 无锁入队
    } else {
        // 未开启时主线程直接处理
        processInputBuffer(client);
    }
}

// 3. IO线程异步执行读数据
// IO线程中:
while (task = ring_buffer_dequeue(my_queue)) {
    readQueryFromClient(task->client);   // 读取数据
    parseCommand(task->client);           // 解析命令
    lookupCommand(task->client);          // 命令查找(Valkey 8.0新增)
}

// 4. 主线程在进入事件监听睡眠前,检查IO线程完成情况
// 通过原子标志 read_state 判断

写数据流程

// 主线程执行命令后
processCommand(client);
// 将响应写入响应缓存
addReply(client, reply);

// 遍历等待写队列
listIter li;
listRewind(server.clients_pending_write, &li);
while ((ln = listNext(&li))) {
    client *c = listNodeValue(ln);
    // 选择IO线程,通过任务队列派发写任务
    iothread_post_write(c);
}

2.3 IO 线程动态调整

Valkey 不是简单地固定 IO 线程数量,而是根据实时负载动态调整活跃线程数

// 伪代码:动态调整活跃IO线程数
int target_threads = min(
    pending_events / events_per_thread,  // 按事件数计算
    max_io_threads                       // 最大不超过配置值(默认15)
);

if (active_threads < target_threads) {
    // 唤醒更多线程(释放锁)
    unlock_thread(thread_id);
} else if (active_threads > target_threads) {
    // 暂停多余线程(加锁使其不再轮询)
    lock_thread(thread_id);
}

关键设计:

  • 减少 IO 线程不直接销毁线程,而是通过加锁使其暂停空轮询
  • 增加 IO 线程只需释放锁
  • 线程亲和性:同一客户端的 IO 请求尽量由同一个 IO 线程处理,提高缓存局部性

2.4 更多任务卸载到 IO 线程

Valkey 8.0 将远不止读写数据的更多任务卸载到了 IO 线程:

任务Redis 6.0Valkey 8.0
网络数据读写IO 线程IO 线程
命令协议解析IO 线程IO 线程
命令字典查找主线程IO 线程
epoll_wait 系统调用主线程IO 线程
对象内存释放主线程IO 线程

事件轮询卸载:epoll_wait 是开销很大的系统调用,Valkey 将其分配给 IO 线程执行,主线程直接检查 IO 线程的轮询结果。

对象释放卸载:命令解析过程中分配的参数对象,释放时由分配它的同一个 IO 线程处理(通过客户端 ID 标识),提高内存局部性。

三、数据预取与内存访问分摊

3.1 为什么需要这些技术?

引入异步 IO 线程后,Valkey 单节点 QPS 达到了约 80 万。瓶颈从 IO 转移到了内存访问

Valkey 使用链式哈希表存储键值对。查找一个 key 的步骤:

  1. 计算 hash 值,定位 bucket
  2. 遍历链表找到 key
  3. 访问 value 对象
  4. 如果是 RAW 编码,还需再次访问内存获取真实数据

每一步都是串行的内存访问,在高速缓存(L1/L2)未命中时,每次访问主存需要约 100ns。现代 CPU 主频 3GHz+,100ns 意味着白白浪费约 300 个时钟周期。

3.2 数据预取(Prefetch)

Valkey 8.0 利用 GCC 的 __builtin_prefetch() 内置函数,在执行命令前批量预取所有即将操作的数据到 CPU 缓存:

// Valkey 8.0 批量预取(简化示意)
void prefetchCommands(client **clients, int count) {
    for (int i = 0; i < count; i++) {
        // 预取命令参数
        for (int j = 0; j < clients[i]->argc; j++) {
            __builtin_prefetch(clients[i]->argv[j]->ptr);
        }
        // 预取命令对应的字典条目
        dictEntry *entry = dictFind(server.db[0]->dict, clients[i]->argv[1]);
        if (entry) {
            __builtin_prefetch(dictGetKey(entry));
            __builtin_prefetch(dictGetVal(entry));
        }
    }
}

原理__builtin_prefetch() 告诉 CPU 预取指定地址的数据到缓存。当后续代码真正访问该地址时,数据已经在缓存中了,避免了等待内存读取。

3.3 内存访问分摊(MAA)

但单纯的预取不够。对于多个 key 的批量操作,如果顺序预取每个 key 的所有步骤,每个 key 仍然需要串行等待。

MAA 的核心思想:交错执行多个 key 的预取步骤。

传统顺序预取(3个key,每个4步):
Key1: step1 → step2 → step3 → step4 → Key2: step1 → step2 → ...
(每个key的步骤之间有内存等待间隙)

MAA 交错预取:
Key1:step1 → Key2:step1 → Key3:step1 → Key1:step2 → Key2:step2 → ...
(在等待Key1:step1数据返回期间,已经开始Key2:step1)
// MAA 交错预取伪代码
void maa_batch_prefetch(client **clients, int count) {
    // 步骤1:预取所有key的bucket
    for (int i = 0; i < count; i++) {
        unsigned int hash = dictHashKey(clients[i]->argv[1]->ptr);
        __builtin_prefetch(dictGetBucket(table, hash));
    }
    // 步骤2:预取所有key的entry(此时bucket已在缓存中)
    for (int i = 0; i < count; i++) {
        dictEntry *entry = dictFindEntry(table, clients[i]->argv[1]->ptr);
        if (entry) __builtin_prefetch(entry);
    }
    // 步骤3:预取所有key的value(此时entry已在缓存中)
    for (int i = 0; i < count; i++) {
        dictEntry *entry = dictFindEntry(table, clients[i]->argv[1]->ptr);
        if (entry) __builtin_prefetch(dictGetVal(entry));
    }
    // 步骤4:预取所有RAW值的真实数据(此时value已在缓存中)
    for (int i = 0; i < count; i++) {
        robj *val = dictGetValue(table, clients[i]->argv[1]->ptr);
        if (val && val->encoding == OBJ_ENCODING_RAW) {
            __builtin_prefetch(val->ptr);
        }
    }
}

3.4 性能提升效果

优化阶段单节点 QPS提升幅度
Redis 6.0 多线程 IO~20 万基准
Valkey 8.0 异步 IO~80 万4x
Valkey 8.0 + Prefetch + MAA~100-120 万5-6x

Valkey 单节点性能已经比肩甚至超越了低版本 Redis 的中等规模集群

四、Valkey 9.0:集群规模的量级跃迁

4.1 原子槽位迁移

Valkey 集群使用哈希槽(Hash Slot)来分布数据,共 16384 个槽。传统 Redis 集群中,迁移槽位时需要分多步操作(标记、迁移、确认),中途如果主节点故障,可能导致数据不一致。

Valkey 9.0 引入了原子槽位迁移(Atomic Slot Migration)

# Valkey 9.0 原子槽位迁移命令
CLUSTER MIGRATE-SLOT <slot> <target-node-id>
# 一次性完成,不需要 CLUSTER SETSLOT 和 MIGRATE 的多步操作

原子性保证

  • 槽位要么在源节点,要么在目标节点,不存在中间状态
  • 迁移过程中客户端请求自动路由
  • 主节点故障不影响迁移一致性

实现原理

  1. 源节点将槽位状态标记为 MIGRATING
  2. 通过内部通道将所有 key 同步到目标节点
  3. 同步完成后,原子性地更新集群元数据
  4. 通知所有节点槽位归属已变更

4.2 集群模式多数据库支持

传统 Redis 集群中,只能使用数据库 0(SELECT 0),这严重限制了集群的使用场景。

Valkey 9.0 打破了这个限制,支持集群模式下的多数据库:

# Valkey 9.0 集群中可以使用多个数据库
SELECT 1
SET user:1001 "Alice"
SELECT 2
SET cache:home "cached_data"

不同应用可以共享同一个 Valkey 集群实例,通过数据库编号隔离数据,解决了资源配置的挑战。

4.3 哈希字段过期

长期以来,Redis 的哈希类型只支持整个 key 的过期,不支持单个字段的过期。Valkey 9.0 引入了哈希字段级过期

# Valkey 9.0 哈希字段过期
HSET session:user123 token "abc123" FIELDEX 3600
# 字段 token 将在 3600 秒后过期

# 检查字段是否过期
HEXPIRE session:user123 300 FIELDS 1 token
# 给 token 字段设置 300 秒过期

这对 session 管理、缓存场景非常实用,不再需要额外的过期管理逻辑。

4.4 集群性能:10 亿 RPS

Valkey 9.0 集群扩展到 2000 个节点,集群吞吐量达到每秒超 10 亿次请求。这得益于:

  • 异步 IO 线程的单节点性能基础
  • 原子槽位迁移降低扩缩容开销
  • 智能核心利用和数据预取的持续优化

五、生产级实战:从 Redis 迁移到 Valkey

5.1 兼容性评估

Valkey 基于 Redis 7.2.4 分叉,协议层面完全兼容 Redis OSS 7.2.4 的 RESP 协议。绝大多数应用无需修改代码即可迁移。

兼容性清单

维度兼容性说明
RESP 协议100%完全兼容
数据类型100%String/List/Hash/Set/ZSet/Stream 等全部支持
Lua 脚本95%+绝大多数脚本兼容,极端边界情况需测试
模块部分Redis 模块不兼容,需要找替代方案
Sentinel替代Valkey 有自己的高可用方案
Cluster增强兼容 Redis 集群协议,并增加了新特性

5.2 部署 Valkey

Docker 部署(快速体验)

# 拉取 Valkey 镜像
docker pull valkey/valkey:9.0

# 启动单节点
docker run -d \
  --name valkey \
  -p 6379:6379 \
  valkey/valkey:9.0 \
  valkey-server --appendonly yes

# 启动时启用异步IO线程
docker run -d \
  --name valkey \
  -p 6379:6379 \
  valkey/valkey:9.0 \
  valkey-server \
  --io-threads 4 \
  --appendonly yes

源码编译部署

# 克隆代码
git clone https://github.com/valkey-io/valkey.git
cd valkey

# 切换到 9.0 分支
git checkout 9.0.0

# 编译(需要 GCC 9+)
make -j$(nproc)

# 运行
./src/valkey-server --io-threads 4

集群部署

# 创建 6 节点配置文件(3主3从)
for port in 7000 7001 7002 7003 7004 7005; do
  mkdir -p cluster-${port}
  cat > cluster-${port}/valkey.conf << EOF
port ${port}
cluster-enabled yes
cluster-config-file nodes-${port}.conf
cluster-node-timeout 5000
appendonly yes
io-threads 4
EOF
done

# 启动所有节点
for port in 7000 7001 7002 7003 7004 7005; do
  ./src/valkey-server cluster-${port}/valkey.conf --daemonize yes --pidfile cluster-${port}/valkey.pid
done

# 创建集群
./src/valkey-cli --cluster create \
  127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \
  127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
  --cluster-replicas 1

5.3 性能压测

# 安装 valkey-benchmark(随 valkey 一起编译)
# 单线程基准测试
./src/valkey-benchmark -h 127.0.0.1 -p 6379 -t set,get -n 1000000 -c 50

# 多线程压测(对比开启/关闭IO线程的差异)
# 关闭IO线程
./src/valkey-server --port 6380 --io-threads 1 --daemonize yes
./src/valkey-benchmark -h 127.0.0.1 -p 6380 -t set,get -n 1000000 -c 200

# 开启IO线程
./src/valkey-server --port 6381 --io-threads 4 --daemonize yes
./src/valkey-benchmark -h 127.0.0.1 -p 6381 -t set,get -n 1000000 -c 200

# Pipeline 压测(更高吞吐量)
./src/valkey-benchmark -h 127.0.0.1 -p 6379 -t set,get -n 1000000 -c 50 -P 16

5.4 数据迁移方案

方案一:在线同步迁移

# 使用 valkey-cli 的 --replica 选项
# 将 Valkey 作为 Redis 的副本,同步完成后切换
./src/valkey-server --port 6380 --replicaof <redis-host> <redis-port>

# 等待同步完成
./src/valkey-cli -p 6380 INFO replication
# 等待 master_link_status:up 和 master_sync_in_progress:0

# 切换为独立节点
./src/valkey-cli -p 6380 REPLICAOF NO ONE

方案二:RDB 文件迁移

# 1. 在 Redis 上生成 RDB
redis-cli BGSAVE
redis-cli LASTSAVE  # 记录时间戳

# 2. 复制 dump.rdb 到 Valkey 数据目录
cp /var/lib/redis/dump.rdb /var/lib/valkey/

# 3. 启动 Valkey(自动加载 RDB)
./src/valkey-server --dir /var/lib/valkey/ --dbfilename dump.rdb

方案三:应用层双写

# Python 双写迁移示例
import redis

redis_client = redis.Redis(host='redis-host', port=6379, decode_responses=True)
valkey_client = redis.Redis(host='valkey-host', port=6379, decode_responses=True)

def dual_write(key, value, ttl=None):
    """双写:先写 Valkey,再写 Redis"""
    valkey_client.set(key, value, ex=ttl)
    redis_client.set(key, value, ex=ttl)

def read(key):
    """读 Valkey,miss 则回源 Redis"""
    value = valkey_client.get(key)
    if value is None:
        value = redis_client.get(key)
        if value is not None:
            valkey_client.set(key, value)
    return value

5.5 Spring Boot 集成

Valkey 完全兼容 Redis 的连接协议,Spring Boot 应用只需修改连接配置:

# application.yml
spring:
  data:
    redis:
      host: valkey-host
      port: 6379
      lettuce:
        pool:
          max-active: 64
          max-idle: 32
          min-idle: 16
// 代码无需任何修改,Spring Data Redis 直接连接 Valkey
@RestController
@RequestMapping("/api/cache")
public class CacheController {
    
    @Autowired
    private StringRedisTemplate redisTemplate;
    
    @GetMapping("/{key}")
    public String get(@PathVariable String key) {
        return redisTemplate.opsForValue().get(key);
    }
    
    @PostMapping("/{key}")
    public void set(@PathVariable String key, @RequestBody String value) {
        redisTemplate.opsForValue().set(key, value, 1, TimeUnit.HOURS);
    }
}

5.6 Go 语言集成

package main

import (
    "context"
    "fmt"
    "log"
    "time"
    
    "github.com/valkey-io/valkey-go"
)

func main() {
    // 连接 Valkey(使用 valkey-go 客户端)
    client, err := valkey.NewClient(valkey.ClientOption{
        InitAddress: []string{"127.0.0.1:6379"},
    })
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()
    
    ctx := context.Background()
    
    // 基本操作
    if err := client.Set(ctx, "user:1001", "Alice", 0).Err(); err != nil {
        log.Fatal(err)
    }
    
    val, err := client.Get(ctx, "user:1001").Result()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("user:1001 = %s\n", val)
    
    // Pipeline 批量操作
    pipe := client.Pipeline()
    for i := 0; i < 100; i++ {
        pipe.Set(ctx, fmt.Sprintf("key:%d", i), fmt.Sprintf("value:%d", i), 0)
    }
    if err := pipe.Exec(ctx); err != nil {
        log.Fatal(err)
    }
    
    // 分布式锁
    ok, err := client.SetNX(ctx, "lock:resource1", "owner1", 10*time.Second).Result()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Lock acquired: %v\n", ok)
}

六、生产环境调优指南

6.1 核心配置参数

# valkey.conf 关键配置

# === 内存管理 ===
maxmemory 12gb                          # 物理内存的 70-80%
maxmemory-policy allkeys-lru             # LRU 淘汰策略

# === 异步 IO 线程 ===
io-threads 4                            # IO 线程数(建议 2-8)
io-threads-do-reads yes                 # IO 线程也处理读操作

# === 持久化 ===
save 3600 1                             # 1 小时内 1 次修改则保存
save 300 100                            # 5 分钟内 100 次修改
save 60 10000                           # 1 分钟内 10000 次修改
rdbcompression no                       # 关闭 RDB 压缩(节省 CPU)
appendonly yes                           # 开启 AOF
appendfsync everysec                     # 每秒刷盘

# === 复制 ===
repl-diskless-sync yes                   # 无盘复制(减少磁盘 IO)
repl-diskless-sync-delay 5               # 等待 5 秒让更多副本加入

6.2 IO 线程数量调优

IO 线程数不是越多越好。根据 AWS 的压测数据:

IO 线程数单节点 QPS(GET)单节点 QPS(SET)建议场景
1(关闭)~50 万~40 万低并发场景
2~80 万~65 万2-4 核机器
4~120 万~100 万4-8 核机器
8~130 万~110 万8-16 核机器
12+~130 万~110 万收益递减,不建议

建议:IO 线程数设置为 CPU 核数的 1/2 到 2/3,最高不超过 8。超过 8 后收益递减明显。

6.3 内存优化

# 开启jemalloc(Valkey 推荐)
# 编译时指定
make MALLOC=jemalloc

# 运行时配置
activedefrag yes                         # 开启主动碎片整理
active-defrag-cycle-min 1                 # 碎片整理最小 CPU 占用
active-defrag-cycle-max 25                # 碎片整理最大 CPU 占用
hash-max-listpack-entries 512             # 小哈希使用 listpack
hash-max-listpack-value 64                # 值小于 64 字节用 listpack

6.4 监控与可观测性

# Valkey 提供了每个槽的性能指标
valkey-cli INFO commandstats
valkey-cli INFO memory
valkey-cli INFO cpu

# 慢查询日志
slowlog-log-slower-than 10000            # 超过 10ms 记录
slowlog-max-len 128                       # 最多保留 128 条

# 查看慢查询
valkey-cli SLOWLOG GET 10

七、Valkey vs Redis:2026 年技术选型

7.1 核心差异对比

维度Valkey 9.0Redis 8.0
许可证BSD 3-Clause(真开源)RSALv2(重新开源但有争议)
单节点 QPS~120 万~20-30 万
集群最大节点20001000(官方推荐)
IO 模型异步任务队列同步多线程
槽位迁移原子迁移多步迁移
哈希字段过期支持不支持
集群多数据库支持仅 DB0
RDMA 支持实验性支持不支持
云厂商支持AWS/Google/Oracle 原生仅 Redis Inc.
模块生态重建中成熟

7.2 选型建议

选 Valkey 的场景

  • 新项目选型,追求性能和开源自由
  • 需要大规模集群(数百节点以上)
  • 使用 AWS ElastiCache / Google Cloud Memorystore(原生支持 Valkey)
  • 需要哈希字段级过期
  • 需要集群多数据库隔离

暂时保留 Redis 的场景

  • 强依赖 Redis 模块(如 RediSearch、RedisJSON、RedisBloom)
  • 使用 Redis Stack 的组合功能
  • 现有 Redis 集群运行稳定,迁移成本高
  • 需要 Redis Inc. 的企业级支持

7.3 混合部署策略

对于已有 Redis 基础设施但想逐步迁移的团队,可以采用混合策略:

# 架构示例:Redis + Valkey 混合部署
# 
# 写热点 → Valkey(高性能写入)
# 读缓存 → Valkey(高吞吐)
# 搜索索引 → Redis + RediSearch(模块依赖)
# 会话管理 → Valkey(字段级过期)
# 消息队列 → 两者均可(Stream 兼容)

八、从 Valkey 看开源数据库的未来

8.1 技术启示

Valkey 的演进给开源数据库带来几个重要启示:

1. 架构级优化比渐进式改进有效得多

Redis 6.0 的多线程 IO 是渐进式的(同步等待模型),只带来了 2x 提升。Valkey 8.0 的异步 IO 是架构级重构(异步任务队列),带来了 5-6x 提升。这说明:当性能接近天花板时,修补不如重构。

2. 内存墙是下一个战场

CPU 单核性能提升缓慢,但内存延迟没有等比例改善。Valkey 的 Prefetch 和 MAA 技术是应对「内存墙」的经典方案,这种思路可以推广到其他内存数据库甚至应用层。

3. 社区分叉可以比原项目更快

Valkey 分叉两年,25.4k Stars,推出了 Redis 尚不具备的原子槽位迁移、哈希字段过期等特性。开源许可证的选择直接影响项目的创新速度。

8.2 展望

Valkey 正在沿着以下方向继续演进:

  • RDMA 支持:实验性支持 RDMA,进一步降低网络延迟
  • 多模态扩展:向量搜索能力的持续增强(与 AI 应用深度融合)
  • Serverless 原生:支持更细粒度的按需扩缩容
  • 可观测性增强:每个槽的细粒度指标,更好的集群诊断能力

九、总结

Valkey 从 Redis 许可证危机中诞生,在两年内完成了从「替代品」到「技术引领者」的蜕变:

  • Valkey 8.0 通过异步 IO 线程、数据预取、内存访问分摊,将单节点性能推到 120 万 QPS
  • Valkey 9.0 通过原子槽位迁移、集群多数据库、哈希字段过期,将集群能力扩展到 2000 节点和 10 亿 RPS

对于新项目,Valkey 已经是值得优先考虑的选择。对于存量 Redis 部署,建议评估迁移成本后制定渐进式迁移方案。无论选择哪个,Valkey 的架构创新——尤其是异步任务队列和内存访问分摊的思路——都值得每个后端工程师深入理解。


参考资源

  • Valkey 官方仓库:https://github.com/valkey-io/valkey
  • Valkey 文档:https://valkey.io/docs/
  • AWS Valkey 性能测试报告
  • 得物技术博客《Valkey 8.0 新特性分析》
复制全文 生成海报 Valkey Redis 内存数据库 开源 缓存

推荐文章

Nginx 负载均衡
2024-11-19 10:03:14 +0800 CST
Go 语言实现 API 限流的最佳实践
2024-11-19 01:51:21 +0800 CST
mysql删除重复数据
2024-11-19 03:19:52 +0800 CST
PHP解决XSS攻击
2024-11-19 02:17:37 +0800 CST
程序员茄子在线接单