这是一份从 Redis 开源版本迁移到 Valkey 的指南。您将学习如何迁移独立的 Redis 服务器实例和 Redis 集群。
本指南提供了在 Docker 中部署的 Redis 服务器和 Valkey 的迁移步骤;但是,它们也适用于其他部署方式。请参阅安装 Valkey 以了解安装选项。
为什么要迁移到 Valkey?
- Valkey 是供应商中立的开源软件
- 通过多线程和双通道复制提高性能
- 通过在集群模式下每个槽位使用一个字典以及在字典中嵌入键来提高内存效率。
迁移兼容性矩阵
您可以将 Redis 服务器迁移到 Valkey。Valkey 与 Redis OSS 7.2 及所有更早的开源 Redis 版本兼容,因为 Valkey 7.2.4 是 Redis 7.2.4 的一个分支。从任何开源 Redis 版本迁移到 Valkey 实际上都是一次升级。
注意:在本指南中,每当提供 `redis-cli` 或 `valkey-cli` 命令的引用时,该引用将仅指向 Valkey 版本的文档。
Redis Community Edition (CE) 7.4 及更高版本不是开源的,其数据文件与 Valkey 不兼容。尽管可能可以将数据从专有 Redis 版本和其他类似 Redis 的软件迁移到 Valkey,但这需要另一种方法,并且不在本文档的讨论范围之内。
下表根据您运行的 Redis 版本提供了迁移选项
Redis | Valkey |
---|---|
OSS 2.x - 7.2.x | 7.2.x |
OSS 2.x - 7.2.x | 8.0 |
CE 7.4 | 不适用 |
迁移独立实例
要将独立的 Redis 服务器迁移到 Valkey,您有以下选项
示例迁移步骤适用于 Redis 7.2.5 和 Valkey 7.2.6 版本。
请注意,如果 Redis 和 Valkey Docker 容器不属于集群的一部分,则它们被视为独立服务器。
物理迁移
这是最简单、最快速的迁移方法。您需要对 Redis 实例进行全新快照,并将其复制到 Valkey。Valkey 在启动时会从快照中读取数据并将其内容恢复到内存中。此方法的权衡点包括
- 关闭 Redis 并等待 Valkey 加载数据的停机时间。
- 对于写入密集型实例可能存在数据丢失的风险。为防止此情况,您必须在开始迁移之前断开所有活动连接。
执行物理迁移的步骤
-
断开与 Redis 实例的所有活动连接。
-
使用 `redis-cli` 连接到您的 Redis 容器,并使用 `INFO KEYSPACE` 命令检查键的数量。这将在后续用于验证整个数据库是否已成功迁移。在此示例中,`keys=6286` 表示数据库中有 6,286 个键。
$ redis-cli -h 127.0.0.1 -p 6379 redis 127.0.0.1:6379> INFO KEYSPACE # Keyspace db0:keys=6286,expires=0,avg_ttl=0
-
检查 Redis 存储其数据库文件的目录 (`dir`) 配置以及数据库文件的名称 (`dbfilename`)。在此示例中,Redis 将备份保存到 `/data/dump.rdb` 文件中
注意:如果您的 Redis Docker 容器的 `/data` 目录已挂载到主机上的某个目录,则 RDB 文件也会写入到该主机目录。
redis 127.0.0.1:6379> CONFIG GET dir dbfilename 1) "dir" 2) "/data" 3) "dbfilename" 4) "dump.rdb"
-
创建备份文件。由于在此示例中所有活动连接都已断开,因此可以使用 `redis-cli` 的 SAVE 命令来创建备份文件。
redis 127.0.0.1:6379> SAVE OK
-
通过按下 `CTRL-D` 或键入 `exit` 退出 `redis-cli`。
-
在您的主机上创建一个目录,您将把 Valkey 容器的 `/data` 目录挂载到该目录。
-
使用以下方法之一将 RDB 文件从 Redis 复制到 Valkey
-
如果 Redis 和 Valkey 容器都挂载到主机目录
将 RDB 文件从挂载到 Redis 容器的主机目录复制到将挂载到 Valkey 容器的主机目录。
-
如果 Redis 容器未挂载到主机目录,但 Valkey 容器已挂载
使用 `docker cp` 命令将 RDB 文件从 Redis 容器内部复制到将挂载到 Valkey 容器的主机目录。
注意:您可能还需要将 RDB 文件复制到第二个位置作为备份。
docker cp redis-container-name:/dir-name/dbfilename <path/on/host>/dbfilename
-
-
停止 Redis 服务器。
-
启动 Valkey
注意:如果您在 Valkey 配置中启用了 AOF,请在首次启动时禁用它。否则,复制的 RDB 文件将不会导入到 Valkey 中。
运行以下命令
docker run -d --name valkey-container-name -v <path/on/host>:<path/in/Valkey/container> image-name
-
要验证数据是否已成功迁移,请确定 Valkey 数据库中的键数量。如果迁移成功,则 Valkey 数据库中的键数量应与您在步骤 2 中获得的 Redis 数据库中的键数量匹配
$ docker exec -it somevalkey valkey-cli valkey 127.0.0.1:6379> INFO KEYSPACE # Keyspace db0:keys=6286,expires=0,avg_ttl=0
-
要退出 `valkey-cli`,请按 `Ctrl-D` 或键入 `exit`。
复制
为了最小化迁移期间的停机时间,您可以使用复制。Redis 和 Valkey 都允许在另一个服务器上重放数据以处理工作负载。
在此场景中,我们将配置 Valkey 作为 Redis 的副本。为了说明目的,Redis 和 Valkey 都运行在连接到同一网络的独立 Docker 容器中。
-
检索 Redis 容器的 IP 地址。将 `myredis` 占位符替换为您的容器名称。在此示例中,`172.17.0.2` 作为 `myredis` 容器的 IP 地址返回。
$ docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' myredis 172.17.0.2
-
确定您的 Redis 容器暴露的端口。请注意,为了清晰起见,响应中并未显示所有字段。在此示例中,`myredis` 容器暴露在 `6379` 端口。
docker container ls CONTAINER ID ... PORTS NAMES bffc575f261a ... 6379/tcp myvalkey ab18318ce820 ... 6379/tcp myredis
-
连接到您的 Valkey 容器并启动 `valkey-cli`,使用 REPLICAOF 命令配置复制。在此示例中,Redis 的 IP 地址为 `172.17.0.2`,端口为 `6379`。请替换为您在步骤 1 和 2 中获取的 Redis 容器的 IP 地址和端口。
docker exec -it myvalkey valkey-cli valkey 127.0.0.1:6379> REPLICAOF 172.17.0.2 6379 OK
-
使用 `INFO REPLICATION` 命令检查 Valkey 中的复制状态。如果存在 `master_link_status:up`,则表示 Redis 和 Valkey 服务器已同步。INFO 命令描述了不同的输出字段。
valkey 127.0.0.1:6379> INFO REPLICATION # Replication role:slave master_host:172.17.0.2 master_port:6379 master_link_status:up master_last_io_seconds_ago:4 master_sync_in_progress:0 ....
-
一旦 Redis 和 Valkey 同步,请验证您的应用程序是否已连接到 Valkey,然后关闭您的 Redis 实例。
注意:自 Redis 7.0 版本发布以来,`SHUTDOWN` 命令会等待一段由 `shutdown-timeout` 配置变量设定的时间,以让任何滞后的副本进行同步。如果 Redis 主节点在与副本同步期间仍有活动写入,则可能存在数据丢失的风险。
您可以通过以下方式之一关闭 Redis
-
使用 `redis-cli`
$ redis-cli SHUTDOWN
-
如果 Redis 是直接在前台启动的(使用 `redis-server`),您只需在运行它的终端中按 `Ctrl-C` 即可停止它。
-
-
在您的 Valkey 容器中,使用 `REPLICAOF` 命令并带上 `NO ONE` 选项来停止 Valkey 复制
valkey 127.0.0.1:6379> REPLICAOF NO ONE OK
-
您可以通过运行 `valkey-cli` 命令 `INFO REPLICATION` 来验证复制是否已停止。如果您看到 `role:master` 和 `connected_slaves:0`,则表明 Valkey 容器现在是主节点,并且不再连接到 Redis 服务器。INFO 命令描述了不同的输出字段。
127.0.0.1:6379> INFO REPLICATION # Replication role:master connected_slaves:0 master_failover_state:no-failover master_replid:8d48c4667129cdb5933f9a12a1d5e6a24899602b master_replid2:602b7046ada6d2d6f0e89657e646d5932cc42791 master_repl_offset:1336 second_repl_offset:1337 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:1336
注意:如果不是为了向后兼容,Valkey 项目不再使用“master”和“slave”这两个词。不幸的是,在当前命令中,这些词是协议的一部分,因此我们只有在自然废弃此 API 时才能移除此类用法。
迁移特定键
物理迁移和复制都会将整个键空间迁移到 Valkey。
在某些情况下,您可能只需要迁移特定的一组关键键。`redis-cli` 命令 MIGRATE 用于迁移一个或多个键。
此示例的要求
-
Redis 和 Valkey Docker 容器在同一网络中,并且可以相互通信。
-
Redis 和 Valkey 容器在没有身份验证的情况下运行。
执行以下步骤
-
确定您希望迁移的键。在此示例中,`message` 和 `mydata` 键正在从 `myredis` 容器迁移,并使用 `redis-cli` 查看它们的当前值。
$ docker exec -it myredis redis-cli redis 127.0.0.1:6379> GET message "Hello Valkey" redis 127.0.0.1:6379> HGETALL mydata 1) "name" 2) "Alice" 3) "age" 4) "33" 5) "country" 6) "Brazil" 7) "favorite food" 8) "beans"
-
检索 Valkey 容器的 IP 地址。将 `myvalkey` 替换为您的 Valkey 容器名称。
$ docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' myvalkey 172.21.0.3
-
在您的 Valkey 容器中启动 `valkey-cli` 并使用 `INFO KEYSPACE` 命令获取数据库编号。在此示例中,数据库编号为 `0` (db0)。
valkey 127.0.0.1:6379> INFO KEYSPACE # Keyspace db0:keys=3,expires=0,avg_ttl=0
注意:如果您尚未迁移或向 Valkey 数据库添加任何数据,则 `INFO KEYSPACE` 命令将不会返回任何数据库编号。您可以在步骤 4 的 `MIGRATE` 命令中使用 `0`。
-
从 Redis 服务器,运行 `MIGRATE` 命令
MIGRATE valkey-ip valkey-port <key | ""> valkey-db-number timeout-value [COPY] [REPLACE] [AUTH password | AUTH2 username password] [KEYS key [key ...]]
例如,要将 `message` 和 `mydata` 键迁移到 IP 地址为 `172.21.0.3` 端口为 `6379` 的 Valkey 实例,命令将类似于
redis 127.0.0.1:6379> MIGRATE 172.21.0.3 6379 "" 0 10 COPY REPLACE KEYS message mydata
其中
- `""` = 表示我们正在迁移多个键。如果您只迁移单个键,可以在此处使用键名。
- `0` = 数据库编号。
- `10`= 与目标服务器通信时允许的最大空闲时间,单位为毫秒。
- `COPY` = 不从 Redis 数据库中移除键。
- `REPLACE` = 替换 Valkey 数据库中已存在的键。
- `KEYS` = 我们正在迁移多个键,后面跟着键名。
-
通过按下 `Ctrl-D` 或键入 `exit` 退出 `redis-cli`。
-
连接到 Valkey 并检查已迁移的键。将 `myvalkey` 替换为您的 Valkey 容器名称。
$ docker exec -it myvalkey valkey-cli valkey 127.0.0.1:6379> GET message "Hello Valkey" valkey 127.0.0.1:6379> HGETALL mydata 1) "name" 2) "Alice" 3) "age" 4) "33" 5) "country" 6) "Brazil" 7) "favorite food" 8) "beans" ....
迁移集群
本节演示如何迁移集群。第一步是将所需数量的 Valkey 节点作为副本添加到现有集群中。一旦新的 Valkey 节点复制了数据,每个 Redis 主节点的一个 Valkey 副本将被提升为新的主节点。迁移完成后,Redis 节点将从集群中移除。
注意:您也可以使用数据迁移工具,例如 RIOT、RedisShake 和 Redis-Migrate-Tool,但这超出了本文档的范围。
此示例的要求
- Redis 和 Valkey 集群节点在同一网络中,并且可以相互通信。
在此场景中,有一个包含 3 个主节点和 3 个副本节点的 Redis 集群正在运行。
执行迁移
-
在其中一个集群节点上使用 `redis-cli` 检查集群的当前状态,并确保所有节点都已连接且处于活动状态。在此集群中,有三个主节点(master)和三个副本节点(slave)。
$ redis-cli -h 127.0.0.1 -p 6379 -c CLUSTER NODES 70beedebe43e422b275ee1a7bac0d3819dedca98 172.22.0.3:6379@16379 master - 0 1725450849000 1 connected 0-5460 8bbe836c59644f7395bbab09c6f8b36bc277e902 172.22.0.5:6379@16379 slave 58061fb2836bdb2f5a0973e1ccfd74a66166f329 0 1725450849510 3 connected 65061b94da5b481dc35c2df7dae13c233d4b3ad2 172.22.0.4:6379@16379 master - 0 1725450848000 2 connected 5461-10922 a242941d0e3edad27a954bc14ac3a3413f3040aa 172.22.0.7:6379@16379 slave 65061b94da5b481dc35c2df7dae13c233d4b3ad2 0 1725450849000 2 connected 3499854656f085ebb77b5b921389a91b7ae9d703 172.22.0.6:6379@16379 slave 70beedebe43e422b275ee1a7bac0d3819dedca98 0 1725450849829 1 connected 58061fb2836bdb2f5a0973e1ccfd74a66166f329 172.22.0.2:6379@16379 myself,master - 0 1725450846000 3 connected 10923-16383
-
创建一个 `valkey.conf` 配置文件并指定以下参数。请注意,此配置文件启用了集群功能。Valkey 配置文件示例 提供了各种配置参数的说明
# valkey.conf file port 6379 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes
-
使用您的自定义配置文件启动 Valkey 实例。以下命令在 Docker 中启动 Valkey
$ docker run -d -v myvalkey/conf:/usr/local/etc/valkey --name valkey-1 --net mynetwork valkey/valkey valkey-server /usr/local/etc/valkey/valkey.conf
其中
- `myvalkey/conf` 是一个本地目录,包含您的 `valkey.conf` 配置文件,该文件被映射到 Docker Valkey 容器内的 `/usr/local/etc/valkey` 目录。
- `valkey-1` 是您的容器名称
- `mynetwork` 是 Redis 集群正在运行的网络名称。
- `valkey/valkey` 是 Valkey 镜像的名称
-
检索 Valkey 实例的 IP 地址;将 `valkey-1` 替换为您的容器名称。
$ docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' valkey-1
-
将您的新 Valkey 节点作为副本添加到 Redis 集群中。将 `redis-1`、`valkey-node-ip` 和 `existing-node-ip` 占位符替换为您的值
$ docker exec -it redis-1 bash $ redis-cli --cluster add-node valkey-node-ip:6379 existing-node-ip:6379 --cluster-replica
-
检查集群状态。`CLUSTER NODES` 命令的输出在 CLUSTER NODES 中有描述。
$ redis-cli -c CLUSTER NODES
在输出中,您将看到新添加的节点作为副本(slave)。例如,我们添加了一个 IP 地址为 `172.22.0.8:6379` 的 Valkey 节点。集群节点列表现在包含一个新条目,如下所示
a98d5bac59672597b8509f24970e413002f896b6 172.22.0.8:6379@16379 slave 58061fb2836bdb2f5a0973e1ccfd74a66166f329 0 1725451086000 3 connected
-
通过运行 `INFO REPLICATION` 命令验证您新添加的 Valkey 节点是否被识别为副本。输出显示了有关节点主节点的信息。
-
在您的新 Valkey 容器中启动 `valkey-cli` 并输入以下命令将其提升为主节点。CLUSTER FAILOVER 提供了更多信息。
docker exec -it valkey-container-name valkey-cli valkey 127.0.0.1:6379> CLUSTER FAILOVER OK
-
使用 `CLUSTER NODES` 命令显示集群状态并验证您的新 Valkey 节点现在是否为新的主节点。
-
重复步骤 3-9,再添加 2 个 Valkey 节点并替换 Redis 主节点。
-
重复步骤 3-7,添加 3 个 Valkey 副本节点。
要将副本添加到特定主节点,请执行以下操作
a. 筛选主节点。连接到集群中的任意节点并运行以下命令,将 `valkey-1` 替换为您的 Valkey 容器名称
$ docker exec -it valkey-1 bash $ valkey-cli -c cluster nodes | grep master 70beedebe43e422b275ee1a7bac0d3819dedca98 172.22.0.3:6379@16379 master - 0 1725451135799 1 connected 0-5460 65061b94da5b481dc35c2df7dae13c233d4b3ad2 172.22.0.4:6379@16379 master - 0 1725451136000 2 connected 5461-10922 58061fb2836bdb2f5a0973e1ccfd74a66166f329 172.22.0.2:6379@16379 myself,master - 0 1725451136000 3 connected 10923-16383
注意:节点 ID 是节点创建时生成的 40 个字符的全局唯一字符串。在此示例中,`70beedebe43e422b275ee1a7bac0d3819dedca98` 是 IP 地址为 `172.22.0.3:6379` 的主节点(master)的 ID。在步骤 b 中将新的 Valkey 副本添加到特定主节点时,需要节点的 ID。
b. 将新节点添加到特定主节点,将 `node-id` 替换为您的节点 ID
$ valkey-cli --cluster add-node 172.22.0.10:6379 172.22.0.2:6379 --cluster-replica --cluster-master-id node-id
-
移除 Redis 节点
redis-cli --cluster del-node 127.0.0.1:6379 node-id
第一个参数是集群中的任意节点,第二个参数是要移除的节点的 ID。
注意:如果不是为了向后兼容,Valkey 项目不再使用“master”和“slave”这两个词。不幸的是,在给定的命令中,这些词是协议的一部分,因此我们只有在自然废弃此 API 时才能移除此类用法。