一、redis集群方案比较
1、哨兵模式
哨兵模式集群主要是通过sentinel监控master的状态,如果master出现异常情况,通过选举slave为master来确保集群的高可用。哨兵模式的性能和高可用方面表现一般,存在主从切换时访问瞬断的情况,并且只有一个主节点提供对外服务,没法提供很高的并发,一个主节点内存还不宜设置过大,会导致持久化文件太大,影响数据恢复和主从复制的效率。
2.高可用集群模式
redis高可用集群是由多个主从节点组成的分布式服务器集群,每一个主从节点都具有对外提供服务的能力,可以横向拓展并发性能,集群中不需要哨兵的监控,每个主从节点都可以监控整个集群的健康状态,当某个主节点出现异常时,就可以通过投票从他的slave选举出新的master。这种集群模式解决了哨兵模式存在的单一的服务提供,存储数据内存有限的问题。
二、redis集群搭建
1.配置文件修改
修改redis.conf文件如下:
(1)daemonize yes
(2)port 6379(分别对每个机器的端口号进行设置)
(3)pidfile /var/run/redis_6379.pid # 把pid进程号写入pidfile配置的文件
(4)dir /usr/local/redis-cluster/6379/(指定数据文件存放位置,必须要指定不同的目录位置,不然会丢失数据)
(5)cluster-enabled yes(启动集群模式)
(6)cluster-config-file nodes-6379.conf(集群节点信息文件)
(7)cluster-node-timeout 10000
(8)# bind 127.0.0.1(bind绑定的是自己机器网卡的ip,如果有多块网卡可以配多个ip,代表允许客户端通过机器的哪些网卡ip去访问,内网一般可以不配置bind,注释掉即可)
(9)protected-mode no (关闭保护模式)
(10)appendonly yes
如果要设置密码需要增加如下配置:
(11)requirepass root (设置redis访问密码)
(12)masterauth root (设置集群节点间访问密码,跟上面一致)
根据自己的具体情况要搭建多少台服务的集群,就可以复制上面配置好的文件,只要将文件里的6379 都修改一下,一共涉及到4个地方,可以用命令:%s/6379/xxxx/g,就可以一次性全部修改成功。
2.创建redis集群
将所有配置好的redis都启动起来,然后只要执行以下一条命令就大功告成:
#后面为所有redis服务的ip和端口号,分别用空格隔开
src/redis-cli -a root --cluster create --cluster-replicas 1 {ip}:{port} {ip2}:{port2} ......
3.验证集群
#只要连上任意一台redis服务都可以
src/redis-cli -a root -c -h {ip} -p {port}
#查看集群信息
cluster nodes
三、redis集群原理
1.数据划分
redis cluster将数据划分为2^14个槽位,每个集群节点都负责一部分槽位,槽位的信息就存储在每个节点中。当客户端来连接集群时,它会得到槽位的信息和各个节点ip,并且缓存到客户端自己本地。客户端将key的值通过Hash运算后,对2^14个槽位取模,然后最终得到具体的节点ip,直接连接该ip进行数据操作。
2.redis集群选取原理
当slave感知到master的状态为fail,slave就会发送故障转移的请求给各个节点,以期选举自己成为master,由于存在多个slave竞争成为master的场景,所以存在以下过程:
-
slave感知到自己的master状态为fail
-
每个slave将自己记录的集群currentEpoch加1,并广播failover_auth_request指令给各个集群节点
-
其他节点收到消息,只有master会响应,验证节点的合法性后,会回复failover_auth_ack指令,对于每个epoch只会响应一次ack
-
当有slave收集master返回的ack,超过集群半数后则选举成功,该slave则成为新的master
-
该slave广播 pong消息通知其他节点自己选举成为了新的master
3.延迟选举
当slave感知到master状态为fail的时候并不是立马就进行选举的,而是有一定的延迟性,等该fial的状态在集群中广播充足后,才会发起选举,因为当集群中的其他master还没感知到fail状态,会拒绝投票。
延迟时间的计算公式:
500ms+Random(0~500)ms+salve_rang*1000ms
slave_rang:表示slave在master复制数据总量的rang,rang越小说明复制的数据多,那么理论上这个slave就会越先发起选举。
4.集群脑裂问题
网络分区导致脑裂后,会有多个主节点对外提供服务,当网络恢复后,会有一个主节点变为从节点,从而导致大量的数据丢失。
可以通过配置 min-replicas-to-write 1这个参数,表示写数据成功最少slave的数量,可以配置最少slave过半就可以避免脑裂后导致的数据丢失问题,但是会影响整个集群的可用性,因为leader正常也可能不能对外提供服务。
5.网络抖动
现实世界中经常会出现网络不稳定的情况,会导致瞬间网络不可访问,但是很快又会恢复,如果集群中一旦发现某个节点网络中断,就判定为fail时,会导致主从不停的切换,频繁的同步数据,redis cluster 提供了一个配置,cluster-node-timeout 参数,表示某个节点失联的时间,然后才断定为fail,从而避免网络导致的主从频繁切换的问题。
6.redis集群节点间的通信机制
redis cluster 采用gossip协议方式进行通讯,来维护集群的元数据(集群节点信息,主从角色,节点数量,各节点共享的数据)信息。
gossip协议包含多种消息:
-
meet: 某个节点发送meet给新加入的节点,新加点加入集群中,新节点开始和集群中的其他节点开始通信
-
ping: 集群中节点间频繁的互相通信,通过ping发送自己的状态信息和集群的元数据,和其他节点交换信息
-
pong: ping和meet消息的响应,包含自己的状态和其他信息,还可以广播和更新
-
fail: 某个节点发现判断另一个节点fail后,则发送fail给其他节点,通知其他节点指定的节点宕机了。
gossip的优点是元数据的更新比较分散,不集中一个地方,最后陆陆续续所有的节点的信息都会更新完成,分担了集中通信的压力,缺点是延时了更新,导致集群的一些操作会比较滞后。