Redis 迁移演练,要覆盖切换后的第一次写入
迁移演练应证明 Lavik 接收新写入之后会发生什么:如何验证数据、判断延迟是否达标,以及如何回退到源端而不悄悄丢失变更。
Redis 迁移在目标端接收第一次新写入之前,往往看起来可以随时回退。在此之前,源端可能仍然保存着完整的应用状态;在此之后,把流量切回去就可能丢掉仅存在于目标端的变更。演练迁移到 Lavik 时,应明确划出这条边界:先证明团队如何处理目标端新增的写入,再认定回退方案已经就绪。
如果值容量的增长正在迫使 Redis 部署增加 DRAM,Lavik 值得纳入评估:它在内存中保留紧凑的键索引,将值存储在文件、裸设备或 SPDK NVMe 命名空间中。这个 Apache 2.0 项目目前处于 0.1.0-beta.1 版本。它支持 Redis 兼容的 RDB 导入导出和 PSYNC,提供了可选的数据传输路径,但这些能力本身并不构成完整的迁移或反向同步流程。
为演练定义明确的数据比较时点
从可丢弃的目标实例开始,书面定义要比较的源端状态。第一次演练可以安排有明确时限的应用写入暂停,让比较基准更容易审查。记录该时点的逻辑数据库、键集合、值类型、过期预期,以及应用必须保持的不变量。如果最终迁移要求持续写入,就把实时流量下的数据收敛另列为验收项;静态导入成功不能证明这一点。
比较逻辑内容,而不是存储文件。Lavik 使用自己的持久化表示,并在启动时重建运行时索引。应验证字符串字节、哈希字段及其值、集合成员、列表顺序、有序集合成员及分数,以及应用实际使用的流信息。如果工作负载包含大型集合或多个逻辑数据库,也要将它们纳入验证。键总数相同,仍可能掩盖一个缺失键和一个多余键,也可能掩盖值类型错误。
过期数据的比较必须考虑时间。Lavik 保存绝对过期时间,读取时将已过期的值视为不存在,物理空间回收则单独进行。记录每次比较的时间,并区分预期持续存活的键与预期在演练期间过期的键。验收应要求过期时刻在预先声明的测量容差内一致,而不是要求不同时刻读取的剩余 TTL 完全相同。磁盘占用量不能代替这种逻辑验证。
把兼容性落实为应用验收条件
使用应用真实的客户端配置和请求序列定义兼容性验收:预期响应、值类型、事务结果、脚本行为和错误处理都必须符合应用要求。Lavik 支持 RESP2/RESP3 和广泛的命令,但并非与 Redis 完全兼容。尤其需要注意,声明的键决定 Lua 和 Function 调用的事务边界,集群多键命令仍要求键处于同一槽位。单机演练不能证明集群场景已经通过验收。
可以先用提供的 basic-commands 操作配方检查基本连接。宿主提供的 10 月 6 日执行回执表明:ARM64 minimal beta 软件包在 Linux 7.0.12-linuxkit、glibc 2.39 环境下通过了其中五项操作和一次优雅重启。这只能证明这项小范围验证的结果,不能证明应用迁移、SPDK 运行、崩溃恢复或完整命令兼容性。发布包要求 Linux 6.1 或更新版本、可用的 io_uring 和兼容的 glibc;最低内核要求并不等于已测试的平台矩阵。
读写第一组键
先安装所选 Linux 软件包和 redis-cli(Ubuntu/Debian:sudo apt-get install redis-tools)。适用于 Minimal 和 Standard。在终端 1 进入解压后包含 ./lavik 的软件包目录,再粘贴下面的 Bash 脚本并保持运行。在终端 2 执行客户端命令。启动 Lavik 无需修改 PATH、使用 root 权限或配置 systemd 服务。
set -euo pipefail
if [ ! -x ./lavik ]; then
echo "Run this from the extracted Lavik package directory (the folder containing ./lavik)." >&2
exit 1
fi
mkdir -p /tmp/lavik-example
if [ ! -e /tmp/lavik-example/data ]; then
fallocate -l 512M /tmp/lavik-example/data
fi
./lavik --bind 127.0.0.1 --port 6379 --metrics-port 0 \
--network kernel --storage uring \
--threads 2 --no-pin-workers --registered-buffer-mb-per-worker 64 \
--shutdown-checkpoint --data-file /tmp/lavik-example/data \
--log-dir /tmp/lavik-example/logs$ redis-cli -h 127.0.0.1 -p 6379 --raw PING
PONG
$ redis-cli -h 127.0.0.1 -p 6379 --raw SET greeting 'hello from Lavik'
OK
$ redis-cli -h 127.0.0.1 -p 6379 --raw GET greeting
hello from Lavik
$ redis-cli -h 127.0.0.1 -p 6379 --raw HSET user:42 name Ada
1
$ redis-cli -h 127.0.0.1 -p 6379 --raw HGET user:42 name
Ada✓ 查看实际执行记录
0.1.0-beta.1 · Linux-7.0.12-linuxkit-aarch64-with-glibc2.39 · 2026-10-06
此记录验证功能行为,不验证 NVMe 性能、断电持久性或 SLA。
{
"recipeId": "basic-commands",
"platform": "Linux-7.0.12-linuxkit-aarch64-with-glibc2.39",
"steps": [
{
"argv": [
"redis-cli",
"-h",
"127.0.0.1",
"-p",
"6379",
"--raw",
"PING"
],
"expected": "PONG",
"actual": "PONG"
},
{
"argv": [
"redis-cli",
"-h",
"127.0.0.1",
"-p",
"6379",
"--raw",
"SET",
"greeting",
"hello from Lavik"
],
"expected": "OK",
"actual": "OK"
},
{
"argv": [
"redis-cli",
"-h",
"127.0.0.1",
"-p",
"6379",
"--raw",
"GET",
"greeting"
],
"expected": "hello from Lavik",
"actual": "hello from Lavik"
},
{
"argv": [
"redis-cli",
"-h",
"127.0.0.1",
"-p",
"6379",
"--raw",
"HSET",
"user:42",
"name",
"Ada"
],
"expected": "1",
"actual": "1"
},
{
"argv": [
"redis-cli",
"-h",
"127.0.0.1",
"-p",
"6379",
"--raw",
"HGET",
"user:42",
"name"
],
"expected": "Ada",
"actual": "Ada"
}
],
"status": "passed",
"binaryVersion": "lavik 0.1.0-beta.1",
"executableOnPath": false,
"workingDirectory": "/opt/lavik",
"sourceCommit": "3955b98d43b312324aa8d52775df52cfb111c0d0",
"packageVersion": "v0.1.0-beta.1",
"gracefulRestart": "passed"
}分别验证流量回退与数据回退
为演练设置两个检查点。第一个检查点中,目标端已接收数据,但尚未承接作为正式数据来源的应用写入;此时切回源端,应不需要协调目标端独有的变更。第二个检查点中,让目标端接收一组范围明确的应用写入。将这些写入记入演练台账,并要求团队在恢复源端流量之前,说明每一项变更如何处理。这份台账是建议采用的验收证据,不是 Lavik 自带的迁移功能。
在执行第二个检查点之前,先确定其回退策略。对于可以重建的缓存数据,可以选择丢弃目标端变更,再从权威数据源重新填充,但验收必须计入回填负载。对于权威数据,则必须另行验证数据协调或反向传输流程,包括写入顺序、删除和过期处理。支持 RDB 导出和 PSYNC,本身不能证明旧源端可以安全恢复服务。如果缺少这套流程,目标端发生写入后的回退就仍未得到验证。
持久性预期应独立于数据传输结果记录。Lavik 普通写入返回成功,并不代表同步 fsync 已完成,因此优雅重启验证不能证明掉电时的行为。进程重启还会创建新的复制历史,需要整个复制组进行全量同步。应明确可接受的数据丢失量和恢复时间,把恢复与重新同步的验收,同客户端连接能否切换分开判断。
把延迟设为切换门槛,也覆盖回退期间
回放流量之前,先为重要操作写明所需的成功吞吐量、p99 和 p99.9 延迟上限、允许的错误率,以及测量时长。使用有代表性的键长、值大小、命令比例、连接数和后台维护活动,在预期流量下评估目标端。还要评估回退期间的表现:数据已经落后的源端,或需要重新填充的缓存,面对的负载与稳定运行时不同。这些是建议的演练验收条件,不是已经取得的测试结果。
9 月 18 日的 SPDK 报告可提供参考,但不能直接作为切换门槛。其中,1000 万键、每值 1 KiB 的 GET 工作负载在 640 个连接时达到 1,012,180 QPS,p99 为 3.599 ms,p99.9 为 5.631 ms。该测量使用内核 TCP、六块 NVMe、16 个 Lavik worker、pipeline=1,窗口为 30 秒。报告包含 22 个新测得的 Lavik 数据点和 124 个复用的其他产品对照数据点,每个配置只测量一次。报告不包含 io_uring,也不能证明各系统具备相同的崩溃持久性,或满足应用的 SLA。
下一次演练可以从一份验收记录开始,分别记录四项结论:应用兼容性、逻辑数据验证、所需负载下的延迟,以及目标端发生写入后的回退。附上准确的软件包标识、选定的数据传输路径、比较时点和每项结论的证据。未经测试的项目保留为“尚未证明”。真正有用的交付物,是在一组已知变更发生之后,仍然经过验证的回退路径,而不只是成功加载了数据的目标实例。