在Redis3.0以前的版本的集群主要是使用哨兵sentinel来监听master节点的状态,如果master节点异常,则会做主从切换。但是哨兵在切断的瞬间访问情况,就会出现问题,没法支持很高的并发。
Redis集群:Redis Cluster 是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性。Redis集群不需要sentinel哨兵,也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种集群模式没有中心节点,可以水平扩展。不推荐超过1000个节点。
一:Redis Cluster搭建方式
1.在第一台机器的/usr/local下创建文件夹redis‐cluster,然后在其下面分别创建2个文件夾如下
mkdir ‐p /usr/local/redis‐cluster mkdir 8001 8004
2.把之前的redis.conf配置文件copy到8001下,修改如下内容:
daemonize yes port 8001 #(分别对每个机器的端口号进行设置) pidfile /var/run/redis_8001.pid # 把pid进程号写入pidfile配置的文件 dir /usr/local/redis‐cluster/8001/ #(指定数据文件存放位置,必须要指定不同的目录位置,不然会 丢失数据) cluster‐enabled yes #(启动集群模式) cluster‐config‐file nodes‐8001.conf #(集群节点信息文件,这里800x最好和port对应上) cluster‐node‐timeout 10000 # bind 127.0.0.1(bind绑定的是自己机器网卡的ip,如果有多块网卡可以配多个ip,代表允许客户端通 过机器的哪些网卡ip去访问,内网一般可以不配置bind,注释掉即可) protected‐mode no #(关闭保护模式) appendonly yes
3.把修改后的配置文件,copy到8004,修改第2、3、4、6项里的端口号
4.另外两台机器也需要做上面几步操作,第二台机器用8002和8005,第三台机器用8003和8006
5.分别启动6个redis实例,然后检查是否启动成功
/usr/local/redis‐5.0.3/src/redis‐server /usr/local/redis‐cluster/800*/redis.conf ps ‐ef | grep redis #查看是否启动成功
6.用redis‐cli创建整个redis集群
/usr/local/redis‐5.0.3/src/redis‐cli ‐‐cluster create ‐‐cluster‐replicas 1 1 *******IP:port****
7.验证集群,没做特殊端口开放,就可以先关闭防火墙
systemctl stop firewalld # 临时关闭防火墙
systemctl disable firewalld # 禁止开机启动
二:Redis集群原理分析
Redis Cluster 将所有数据划分为 16384 个 slots(槽位), 每个节点负责其中一部分槽位。槽位的信息存储于每个节点中。
槽位定位算法
Cluster 默认会对 key 值使用 crc16 算法进行 hash 得到一个整数值,然后用这个整数值对 16384 进行取模 来得到具体槽位。
HASH_SLOT = CRC16(key) mod 16384
Redis集群节点间的通信机制
redis cluster节点间采用gossip协议进行通信
维护集群的元数据的有两种方式:集中式和gossip
集中式:
优点在于元数据的更新和读取,时效性非常好,一旦元数据出现变更就立即会更新到集中式的存储中,其他节点读取的时候立即就可以立即感知到;不足在于所有的元数据的更新压力都全部集中在一个地方,可能导致元数据的存储压力。(zookeeper)
gossip:
优点在于元数据的更新比较分散,不是集中在一个地方,更新请求会陆陆续续打到所有节点上去更新,有一定的延时,降低了压力;缺点在于数据更新延时有可能导致集群的一些操作会滞后。
每个节点都有一个专门用于节点间gossip通信的端口,就是自己提供服务的端口号+10000,比如7001,那么 用于节点间通信的就是17001端口。
每个节点每隔一段时间都会往另外几个节点发送ping消息,同时其他几 点接收到ping消息之后返回pong消息。
网络抖动
真实世界的机房网络往往并不是风平浪静的,它们经常会发生各种各样的小问题。比如网络抖动就是非常常见 的一种现象,突然之间部分连接变得不可访问,然后很快又恢复正常。
为解决这种问题,Redis Cluster 提供了一种选项clusternodetimeout,表示当某个节点持续 timeout 的时间失联时,才可以认定该节点出现故障,需要进行主从切换。如果没有这个选项,网络抖动会导致主从频 繁切换 (数据的重新复制)
三:Redis集群选举原理分析
当slave发现自己的master变为FAIL状态时,便尝试进行Failover,以期成为新的master。由于挂掉的master 可能会有多个slave,从而存在多个slave竞争成为master节点的过程, 其过程如下
- slave发现自己的master变为FAIL
- 将自己记录的集群currentEpoch加1,并广播FAILOVER_AUTH_REQUEST 信息
- 其他节点收到该信息,只有master响应,判断请求者的合法性,并发送FAILOVER_AUTH_ACK,对每一个 epoch只发送一次ack
- 尝试failover的slave收集master返回的FAILOVER_AUTH_ACK
- slave收到超过半数master的ack后变成新Master(这里解释了集群为什么至少需要三个主节点,如果只有两 个,当其中一个挂了,只剩一个主节点是不能选举成功的)
- slave广播Pong消息通知其他集群节点。
从节点并不是在主节点一进入 FAIL 状态就马上尝试发起选举,而是有一定延迟,一定的延迟确保我们等待 FAIL状态在集群中传播,slave如果立即尝试选举,其它masters或许尚未意识到FAIL状态,可能会拒绝投票
•延迟计算公式:
DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms
SLAVE_RANK表示此slave已经从master复制数据的总量的rank。Rank越小代表已复制的数据越新。这种方 式下,持有最新数据的slave将会首先发起选举
四:集群脑裂数据丢失问题
redis集群没有过半机制会有脑裂问题,网络分区导致脑裂后多个主节点对外提供写服务,一旦网络分区恢复, 会将其中一个主节点变为从节点,这时会有大量数据丢失。
为了规避,在redis加如下配置:
min‐replicas‐to‐write 1 #写数据成功最少同步的slave数量
Redis集群为什么至少需要三个master节点,并且推荐节点数为奇数?
因为新master的选举需要大于半数的集群master节点同意才能选举成功,如果只有两个master节点,当其中 一个挂了,是达不到选举新master的条件的。
奇数个master节点可以在满足选举该条件的基础上节省一个节点,比如三个master节点和四个master节点的 集群相比,大家如果都挂了一个master节点都能选举新master节点,如果都挂了两个master节点都没法选举 新master节点了,所以奇数的master节点更多的是从节省机器资源角度出发说的。
原文链接:https://blog.csdn.net/qq_35529931/article/details/124243888
原创文章,作者:优速盾-小U,如若转载,请注明出处:https://www.cdnb.net/bbs/archives/16759