集群原理
集群主要解决两个问题
- 数据同步
-
Navie方案
简单粗暴
部署多台一模一样的Redis服务,使用负载均衡分摊压力及监控服务状态
优势
-
不足
为了保证数据一致,需要大量的数据同步
-
Redis集群方案
基于分而治之的思想
- 将Key按照某种规则划分成多个分区,将不同的分区存放在不同的节点上
- 使用哈希算法(CRC16(key) mod 16383)将key映射到16384个slot上
- 每个节点负责一定范围的slot,所有节点组成的集群覆盖了所有的slot
CRC16算法简化了扩缩容时数据分片和迁移的难度,节点只需要维护自身和slot的映射关系
架构优化
slave节点冗余备份master节点,高峰时可以提供读能力
- 由于key映射到slot的算法是固定公开的,客户端内部维护key到slot的映射关系,找到正确的节点,减少MOVED重定向
- 节点通信公共Gossip协议实现最终一致性
- 节点下线
- 主观下线 pfail:节点A在cluster-node-timeout时间内和节点B的ping/pong消息失败,A主观标记B下线,并将状态消息传播给集群内其他节点
- 客观下线 fail:当集群内多数master节点标记他为主观下线后,触发客观下线
故障恢复
修改配置文件后以集群模式启动新节点
# 开启集群模式
cluster-enabled yes
# 节点超时时间,单位毫秒
cluster-node-timeout 15000
# 集群节点信息文件
cluster-config-file "nodes-6379.conf"
发送meet消息
使用客户端发起命令
cluster IP PORT
,节点会发送meet消息将IP和PORT加入集群
分配slot
- 加入集群后得到“空”集群,把slot分配给master
cluster add addslots {<a>...<b>}
将a-b的slot都分配给节点cluster nodes
查看各个节点负责的slot,以及节点IDcluster replicate <nodeId>
将该节点分配为指定的master节点的备份 命令直接创建集群
```redis 5
redis-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
旧版本
./redis-trib.rb create —replicas 1 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 ```
集群伸缩
扩容
- 扩容操作与创建集群操作类似,不同的在于最后一步是将slot从已有的节点迁移到新的节点
- 启动新节点,同创建集群
- 将新节点加入到集群:使用
redis-cli --cluster add-node
命令将新节点加入集群(内部meet消息) - 迁移slot和数据:使用
redis-cli --cluster reshard
进行slot迁移 -
收缩
为了安全删除节点,Redis集群只能下线没有slot的节点
- 迁移slot和数据:使用
redis-cli --cluster reshard
进行slot迁移 - 下线节点:使用
redis-cli --cluster del-node
删除节点(内部forget消息) -
持久化
RDB
即使设置了
save ""
视图关闭RDB,但还是可能会触发- 执行shutdown时,如果没有开启AOF,也会触发RDB持久化
- 不管save如何配置,只要RDB文件存在,redis启动时就会去加载该文件
AOF