Redis集群
Redis主从复制集群: slaveof,可redis.conf配置也可客户端命令
PSYNC:初始全量复制,master进行bgsave生成rdb传给slave
断线后,slave重新连上master并传递runID(断线前复制的服务器ID)和offset(自己运行到的指令位置),master根据runID是否是自己且offset是否在缓冲区内决定全量还是部分复制
命令传播:master执行命令,且将命令放入缓冲区和发给slave
slaveof:slave建立连接,进行PING检测网络状况,可能鉴权后进行同步
slave定时进行心跳(并报告自己的offset,若master发现命令丢失重发,并实现min-slaves)
实践说明:slave可读但不建议读(若未开启tcp的NO_DELAY会带来脏读,数据有点过期),不用读写分离,全走master即可,内存读写很快的,slave作为高可用
手动故障转移:麻烦,找一个slave变成master(slaveof no one),其他slave(slaveof ip port),修改各节点redis.conf
自动故障转移(Sentinel):哨兵对各节点心跳,若超过指定个数哨兵认为某master故障,则由哨兵完成转移
Sentinel(哨兵):多Sentinel组成的系统可监视多个主从集群,Sentinel就是一特殊Redis服务器,配置文件给定监视的master列表,创建到master的命令连接(自己是master的客户端)和订阅连接,定时向master发INFO来获取其slave状态(slave数量可能变动,需定时获取),创建到slave的命令连接和订阅连接并定时INFO各slave,各Sentinel定时向被监视(master和slave)的服务器的_sentinel_:hello
频道发消息并订阅此频道,可实现监视某服务器的Sentinel互相发现,Sentinel互相建立命令连接(A连B,B连A,互为客户端)
Sentinel定时PING其它(master,slave,Sentinel)服务器,若指定时间无法获取有效回复(超时或获取的是无效回复),认为其主观下线,询问其它Sentinel,若认为下线的达到一定数量(quorum),则认为客观下线,选举Leader Sentinel(一Sentinel一票,超过半数的当选,无过半则重选),Leader Sentinel进行故障转移,找一个slave变成master(先过滤,后按优先级/复制偏移量排序)(slaveof no one),其他slave(slaveof ip port),原来的master上线后对其slaveof
Redis数据分片集群:
cluster-enabled yes:启动集群模式
cluster meet ip port:将ip+port对应节点加入当前节点所在集群,三次握手,MEET,PONG,PING,互相就认识了,都有对方的clusterNode,Gossip协议让其他节点也去和新节点握手
集群上线:所有slot都有节点在处理
cluster addslots : 将某个或某些slot指派给当前node
每个clusterNode通过bitmap记录了node负责的slot,slot指派消息会互相传播,clusterState记录了每个slot对应的clusterNode
不按照一致性hash(分散性不好可能导致负载不均衡),CRC16[key]&16383确定key属于哪个slot,此slot由当前node负责就直接处理,否则返回MOVED重定向错误,若为集群客户端(-c,可连接多node)则自动转向新node执行命令,普通客户端则打印MOVED错误
集群模式node只使用0号数据库
重新分片:改变slot的指派node,同时迁移对应slot的键值对,在线进行,即重新分片时也可以接受客户端请求,redis-trib负责操作,一个slot一个slot进行迁移,目标node做好导入准备,源node做好迁移准备,迁移过程中slot还是由源node负责,但是slot的部分数据可能已经导入到目标node了,源node找不到key且自己在迁移那么返回ASK重定向错误,集群客户端向目标node发送ASKING命令后去获取目标node的数据。因为slot暂时还不属于目标node,直接访问就MOVED错误了,所以先ASKING,ASKING一次有效,即ASKING后只可以特殊访问一次属于正在导入的slot
cluster replicate node_id: 当前node配置为某node的从node,开始对master进行复制,消息传播出去其他node也会知道,此slave不可读, 某节点的Master和Slave都挂了集群下线
PING,若规定时间未收到PONG,疑似下线,收到其他node对某node的判断放入clusterNode的下线报告链表内,过半主节点认为疑似下线,则判断为下线,广播FAIL消息,所有node都知道某node下线,此node的slave开始故障转移,各slave为自己拉选票(先到先得),master才能投票,某slave收到过半选票为新master,选不出来重新选,新master进行slaveof no one,获取所有slot指派,其他slave为新master的slave,包括原来的master上线后也为新master的slave,一切搞定后,新master广播PONG告知各node
MEET PING PONG FAIL PUBLISH 五种消息
各消息含统一header,header含消息类型和发送者的信息如slot指派情况
PING:各node都每秒随机选5个node, 5个内选最长没ping过的发PING消息
PONG:收到MEET或PING,故障转移完成时
MEET PING PONG含相同消息体,Gossip协议(扩散到整个cluster需一定时间),内置随机两个node的信息,接收者可更新对node的认识或发现是新node去握手
FAIL:广播
PUBLISH :客户端向某node发送PUBLISH 命令,node向某channel发消息,node广播PUBLISH 消息,各node都向某channel发消息
还没有评论,来说两句吧...