最近项目组对老旧系统中的Redis集群进行改造升级, 由哨兵模式改造为集群模式. 较常用的升级方式需要停机拷贝数据文件, 再重新分配hash槽中的数据, 流程比较长, 操作也比较复杂.
这里我们使用一种比较简单的方式完成快速迁移.
1. Redis单节点部署
为模拟实际情况, 首先准备一个redis 单节点的服务.
redis.conf配置如下:
bind 127.0.0.1 -::1
protected-mode yes
port 6379
pidfile /var/run/redis_6379.pid
dbfilename dump.rdb
dir ./
在配置文件所在路径, 执行服务启动命令, 一个单节点服务就部署完成了:
redis-server redis.conf
2. Redis cluster集群节点部署
再部署一套redis cluster集群.
redis.conf集群模式下的配置文件, 注意与单机部署方式是不同的.
port 7001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
bind 127.0.0.1
protected-mode no
dir ./
redis的集群模式最少需要3个节点, 其他两个节点的配置与之类似, 修改下端口即可, 因为redis会生成一些配置文件, 所以3个节点的redis.conf需分别放置在不同的目录下.
分别进入各目录下, 以单节点相同的方式启动各节点:
redis-server redis.conf
3. Redis cluster集群创建, 并分配hash槽
Redis Cluster 在5.0之后取消了ruby脚本 redis-trib.rb的支持, 可以直接使用redis-cli的--cluster子命令进行集群创建.
$ redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003
>>> Performing hash slots allocation on 3 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
M: 8d3f35fef0be4237f5931bd27942bbdd334aa358 127.0.0.1:7001
slots:[0-5460] (5461 slots) master
M: 526fadd318b19dad9f81abdfeb7f08fd5d7d791a 127.0.0.1:7002
slots:[5461-10922] (5462 slots) master
M: af0f7fe657a0a0ca47c025e6be50d56e43a10f17 127.0.0.1:7003
slots:[10923-16383] (5461 slots) master
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
....
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: 8d3f35fef0be4237f5931bd27942bbdd334aa358 127.0.0.1:7001
slots:[0-5460] (5461 slots) master
M: af0f7fe657a0a0ca47c025e6be50d56e43a10f17 127.0.0.1:7003
slots:[10923-16383] (5461 slots) master
M: 526fadd318b19dad9f81abdfeb7f08fd5d7d791a 127.0.0.1:7002
slots:[5461-10922] (5462 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
4. 数据导入
这里以数据复制方式(--cluster-copy)进行数据导入, 源节点服务中数据不会进行删除处理; 当然也可以使用--cluster-replace方式, 覆盖现有数据,并删除源节点数据,这种方式的缺点就是, 对于已经移走的数据, 进行修改或查询时, 会出现数据偏差.
$ redis-cli --cluster import 127.0.0.1:7001 --cluster-from 127.0.0.1:6379 --cluster-copy
>>> Importing data from 127.0.0.1:6379 to cluster 127.0.0.1:7001
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: 8d3f35fef0be4237f5931bd27942bbdd334aa358 127.0.0.1:7001
slots:[0-5460] (5461 slots) master
M: af0f7fe657a0a0ca47c025e6be50d56e43a10f17 127.0.0.1:7003
slots:[10923-16383] (5461 slots) master
M: 526fadd318b19dad9f81abdfeb7f08fd5d7d791a 127.0.0.1:7002
slots:[5461-10922] (5462 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
*** Importing 1 keys from DB 0
Migrating a to 127.0.0.1:7003: OK
更多关于集群操作命令及参数可以通过参考如下命令查询.
redis-cli --cluster help
以上, 就是利用redis的原生命令代替rdb文件拷贝以及复杂的槽迁移等操作.
这里只是介绍了redis数据的迁移过程, 对于数据的正确性和完整性是无法保证, 是需要代码逻辑中进行双写等操作来保证完成的.