Redis 10章——集群(cluster)
一、是什么
(1)定义
(2)官网
Redis cluster specification | Docs
(3)一图
(4)一句话
- Redis集群是一个提供在多个Redis节点间共享数据的程序集
- Redis集群可以支持多个master
二、能干嘛
- Redis集群支持多个master,每个master又可以挂载多个slave
- 读写分离
- 支持数据的高可用
- 支持海量数据的读写存储操作
- 由于Cluster自带Sentinel的故障转移机制,内置了高可用的支持,无需再去使用哨兵功能
- 客户端与Redis的节点连接,不再需要连接集群中所有的节点,只需要任意连接集群中的一个可用节点即可
- 槽点slot负责分配到各个物理服务节点,由对应的集群来负责维护节点、插槽和数据之间的关系
三、集群算法—分片—槽位slot
(1)官网出处

(2)redis集群的槽位slot

(3)Redis集群的数据分片
(4)它俩的优势

(5)slot槽位映射,一般业界有3种解决方案
3.5.1哈希取余分区

3.5.2一致性哈希算法分区
(1)是什么
(2)能干嘛
- 提出一致性Hash解决方案
- 目的是当服务器个数发生变动时
- 尽量减少影响客户端到服务器的映射关系
(3)3大步骤
- 算法一致性构建哈希环
- redis服务器IP节点映射
- key落到服务器的落键规则
(4)优点
- 一致性哈希算法的容错性
- 一致性哈希算法的扩展性
(5)缺点
一致性哈希算法的数据倾斜问题
(6)小总结
3.5.3哈希槽分区
- 是什么
- 哈希槽计算
(6)经典面试题:为什么𝑅𝑒𝑑𝑖𝑠集群的最大槽数是16384个?
3.6.1为什么redis集群的最大槽数是16384个?

3.6.2说明1

3.6.3说明2
3.6.4计算理论
3.6.5不保证强一致性
redis集群不保证强一致性,这意味着在特定的条件下,Redis集群可能会丢掉一些被系统收到的写入请求命令
四、集群环境案例步骤
(1)3主3从redis集群配置
4.1.1找3台真实虚拟机,各自新建
mkdir -p /myredis/cluster
注意:现在这个文件在/(即根目录下)
4.1.2新建6个独立的redis实例服务
(1)IP: 192.168.200.130 + 端口6381/6382
- vim /myredis/cluster/redisCluster6381.conf
bind 0.0.0.0 daemonize yes protected-mode no port 6381 logfile "/myredis/cluster/cluster6381.log" pidfile /myredis/cluster6381.pid dir /myredis/cluster dbfilename dump6381.rdb appendonly yes appendfilename "appendonly6381.aof" requirepass 111111 masterauth 111111 cluster-enabled yes cluster-config-file nodes-6381.conf cluster-node-timeout 5000
- vim /myredis/cluster/redisCluster6382.conf
bind 0.0.0.0 daemonize yes protected-mode no port 6382 logfile "/myredis/cluster/cluster6382.log" pidfile /myredis/cluster6382.pid dir /myredis/cluster dbfilename dump6382.rdb appendonly yes appendfilename "appendonly6382.aof" requirepass 111111 masterauth 111111 cluster-enabled yes cluster-config-file nodes-6382.conf cluster-node-timeout 5000
(2)IP:192.168.0.100 + 端口6383/6384
- vim /myredis/cluster/redisCluster6383.conf
bind 0.0.0.0 daemonize yes protected-mode no port 6383 logfile "/myredis/cluster/cluster6383.log" pidfile /myredis/cluster6383.pid dir /myredis/cluster dbfilename dump6383.rdb appendonly yes appendfilename "appendonly6383.aof" requirepass 111111 masterauth 111111 cluster-enabled yes cluster-config-file nodes-6383.conf cluster-node-timeout 5000
- vim /myredis/cluster/redisCluster6384.conf
bind 0.0.0.0 daemonize yes protected-mode no port 6384 logfile "/myredis/cluster/cluster6384.log" pidfile /myredis/cluster6384.pid dir /myredis/cluster dbfilename dump6384.rdb appendonly yes appendfilename "appendonly6384.aof" requirepass 111111 masterauth 111111 cluster-enabled yes cluster-config-file nodes-6384.conf cluster-node-timeout 5000
(3)IP:192.168.0.100 + 端口6385/6386
- vim /myredis/cluster/redisCluster6385.conf
bind 0.0.0.0 daemonize yes protected-mode no port 6385 logfile "/myredis/cluster/cluster6385.log" pidfile /myredis/cluster6385.pid dir /myredis/cluster dbfilename dump6385.rdb appendonly yes appendfilename "appendonly6385.aof" requirepass 111111 masterauth 111111 cluster-enabled yes cluster-config-file nodes-6385.conf cluster-node-timeout 5000
- vim /myredis/cluster/redisCluster6386.conf
bind 0.0.0.0 daemonize yes protected-mode no port 6386 logfile "/myredis/cluster/cluster6386.log" pidfile /myredis/cluster6386.pid dir /myredis/cluster dbfilename dump6386.rdb appendonly yes appendfilename "appendonly6386.aof" requirepass 111111 masterauth 111111 cluster-enabled yes cluster-config-file nodes-6386.conf cluster-node-timeout 5000
(4)启动6台redis主机实例
- 上面三台机器的配置(后两个操作一样):
- 启动如下图:
4.1.3通过redis-cli命令为6台机器构建集群关系
- 构建主从关系命令(只要一台机器使用该命令即可)
redis-cli -a 111111 --cluster create --cluster-replicas 1 192.168.200.130:6381 192.168.200.130:6382 192.168.200.131:6383 192.168.200.131:6384 192.168.200.132:6385 192.168.200.132:6386
- 注意:提示信息一定要输入yes,而不是y
- 集群连接成功就一定会产生nodes文件
- 一切OK的话,三从三主搞定
4.1.4链接进入6381作为切入点,查看并检验集群状态

注意:
cluster nodes // 查看集群的主从关系
cluster info // 查看集群信息
info replication // 查看主从
(2)3主3从redis集群读写
4.2.1对6381新增两个key,看看效果如何
4.2.2为什么报错
4.2.3如何解决

4.2.4查看集群信息
4.2.5查看某个key该属于对应的槽位值CLUSTER KEYSLOT 键名称
(3)主从容错切换迁移案例
4.3.1容错切换迁移
(1)主6381和从机切换,先停止主机6381
- 6381主机停了,对应的真实从机上位
- 6381作为1号主机分配的从机以实际情况为准,具体是几号机器就是几号机器
(2)再次查看集群信息,本次6381主6384从
(3)停止主机6381,再次查看集群信息
6384成功上位并正常使用
(4)随后,6381原来的主机回来了,是否会上位?
恢复前:
恢复后:
说明:6381不会上位并以从节点形式回归
4.3.2集群不保证数据一致性100%OK,一定会有数据丢失的情况
Redis集群不保证强一致性这意味着在特定的条件下,Redis集群可能会丢掉一些被系统收到的写入请求命令
4.3.3手动故障转移 or 节点从属调整该如何处理
(1)上面一换后6381和6384主从关系对调了,和原始设计图不一样了,该如何
(2)重新登陆6381机器
(3)常用命令
CLUSTER FAILOVER // 让谁上位 就在谁的端口号下执行这个命令
(4)主从扩容案例
4.4.1新建6387、6388两个服务实例配置文件+新建后启动
IP:192.168.200.132+端口6387/端口6388
- vim /myredis/cluster/redisCluster6387.conf
bind 0.0.0.0 daemonize yes protected-mode no port 6387 logfile "/myredis/cluster/cluster6387.log" pidfile /myredis/cluster6387.pid dir /myredis/cluster dbfilename dump6387.rdb appendonly yes appendfilename "appendonly6387.aof" requirepass 111111 masterauth 111111 cluster-enabled yes cluster-config-file nodes-6387.conf cluster-node-timeout 5000
- vim /myredis/cluster/redisCluster6388.conf
bind 0.0.0.0 daemonize yes protected-mode no port 6388 logfile "/myredis/cluster/cluster6388.log" pidfile /myredis/cluster6388.pid dir /myredis/cluster dbfilename dump6388.rdb appendonly yes appendfilename "appendonly6388.aof" requirepass 111111 masterauth 111111 cluster-enabled yes cluster-config-file nodes-6388.conf cluster-node-timeout 5000
4.4.2启动87/88两个新的节点实例,此时他们自己都是master
- redis-server /myredis/cluster/redisCluster6387.conf
- redis-server /myredis/cluster/redisCluster6388.conf
4.4.3将新增的6387节点(空槽位)作为master节点加入集群

注意:引路人可以是集群中任意一个存在的节点
4.4.4检查集群情况第一次
redis-cli -a 111111 --cluster check 192.168.200.130:6381
4.4.5重新分派槽位
redis-cli -a 111111 --cluster reshard 192.168.200.130:6381
what is the receiving node ID?填6387的id
4.4.6检查集群情况第二次
4.4.7槽位分派说明
4.4.8为主节点6387分配从节点6388
redis-cli -a 111111 --cluster add-node 192.168.200.132:6388 192.168.200.132:6387 --cluster-slave --cluster-master-id 这里填6387的id
4.4.9检查集群情况第三次


(5)主从缩容案例
4.5.1目的:6387和6388下线
4.5.2检查集群情况第一次,先获得从节点6388的节点ID
redis-cli -a 密码 --cluster check 192.168.200.132:6388
4.5.3从集群中将4号从节点6388删除
redis-cli -a 密码 --cluster del-node ip:从机端口 从机6388节点ID
4.5.4将6387的槽号情况,重新分配,本例将清出来的槽号都给6381
redis-cli -a 111111 --cluster reshard 192.168.200.130:6381
4.5.5检查集群情况第二次
4.5.6将6387删除
redis-cli -a 密码 --cluster del-node ip:端口 6387节点ID