redis cluster集群提供了扩容功能,以解决在线动态扩容和数据迁移等问题。Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希槽 (hash slot)的方式来分配的。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384
。
注意的是:必须要3个以后的主节点,否则在创建集群时会失败,我们在后续会实践到。
集群节点
请参考基于Redis Cluster的分布式缓存部署篇(三)
主机名 | 主机地址 | 端口 | 备注 |
---|---|---|---|
nodea-7000 | 10.128.31.104 | 7000 | 主机A7000端口节点 |
nodea-7001 | 10.128.31.104 | 7001 | 主机A7001端口节点 |
nodeb-7000 | 10.128.31.108 | 7000 | 主机B7000端口节点 |
nodeb-7001 | 10.128.31.108 | 7001 | 主机B7001端口节点 |
nodec-7000 | 10.128.31.109 | 7000 | 主机C7000端口节点 |
nodec-7001 | 10.128.31.109 | 7001 | 主机C7001端口节点 |
新增集群节点
主机名 | 主机地址 | 端口 | 备注 |
---|---|---|---|
noded-7000 | 10.128.31.103 | 7000 | 主机D7000端口节点 |
noded-7001 | 10.128.31.105 | 7001 | 主机E7001端口节点 |
扩容准备
启动新节点
启动命令
1 | redis-server ~/redis/etc/redis-7000.conf |
重新规划槽位
原集群槽位
节点 | 槽位号 | 备注 |
---|---|---|
nodea | 0-5460 | 节点A槽位段 |
nodeb | 5461-10922 | 节点B槽位段 |
nodec | 10923-16383 | 节点C槽位段 |
新集群槽位,新增一组节点,按平均分配策略各组节点槽16384/4=4096
节点 | 槽位号 | 备注 |
---|---|---|
nodea | 0-4095 | 节点A槽位段 |
nodeb | 4096-8491 | 节点B槽位段 |
nodec | 8492-12287 | 节点C槽位段 |
nodec | 12288-16383 | 节点D槽位段 |
上面的调整方案槽位移动多,可以将每组节点的1365槽分配给新增节点
集群扩容
添加Master节点
添加节点,需要知道节点IP和port,通常情况是同时添加两个节点。使用redis-trib.rb add-node分别将两个新结点添加到集群中,按照顺序,前一个节点作为Master,后一个作为其Slave。执行命令
1 | redis-trib.rb add-node 10.128.31.103:7000 10.128.31.104:7000 |
查看Mater节点NodeId
1 | redis-cli -h 10.128.31.104 -p 7000 cluster nodes |
添加Slave节点
集群节点是一主多备,添加master节点,再给Master添加Salve,不能挂起或关闭原有节点。添加从节点的命令
1 | redis-trib.rb add-node --slave --master-id 2aeade86ccf4027a56df26d275db91cd3c689fe9 |
迁移槽数据
1 | redis-trib.rb reshard 10.128.31.104:7000 |
执行命令询问需要迁移的槽位数量,打印一份期望的执行结果,确认后输入4096
输入接收槽位的集群节点ID,也就是10.128.31.103:7000的节点node id
全部节点的迁移槽位,则输入all,最终每个节点迁移迁移一部分槽
新槽位分布
节点 | 槽位号 | 备注 |
---|---|---|
nodea | 0-4095 | 节点A槽位段 |
nodeb | 4096-8491 | 节点B槽位段 |
nodec | 8492-12287 | 节点C槽位段 |
nodec | 12288-16383 | 节点D槽位段 |
总结
- 迁移过程中允许slot继续有操作,redis保证了迁移过程中slot的正常访问。
- 集群扩容前后,slot总数保存不变,每个集群中的节点持有总slot的一部分,有效的保证了数据的完整性。