1.redis数据分片
(1)Redis 集群有 16384 个哈希槽,我们只是使用键的 CRC16 编码对 16384 取模来计算一个指定键所属的 哈希槽。 每一个 Redis 集群中的节点都承担一个哈希槽的子集,
例如,你可能有一个 3 个节点的集群,其中:
节点 A 包含从 0 到 5500 的哈希槽。
节点 B 包含从 5501 到 11000 的哈希槽。
节点 C 包含从 11001 到 16384 的哈希槽。
(2)redis 添加或者移除节点
如果想添加一个新节点 D,从节点 A,B, C 移动一些哈希槽到节点 D。同样地,如果想从集群中移除节点 A,只需要移动 A 的哈希槽到 B 和 C。 当节点 A 变成空的以后,就可以从集群中彻底删除它。 因为从一个节点向另一个节点移动哈希槽并不需要停止操作(哈希槽是逻辑概念),所以添加和移除节点,或者改变节点持有 的哈希槽百分比,都不需要任何停机时间(downtime)。
2.主从原理
(1)主从复制
全量同步:
1)从服务器连接主服务器,发送SYNC命令;
2)主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
增量同步
Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。
增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。
(摘自 https://www.cnblogs.com/hepingqingfeng/p/7263782.html)
(2)读写分离
Master只负责写和同步数据给Slaver,Slaver承担了被读的任务,所以Slaver的扩容只能提高读效率不能提高写效率。
3.哨兵机制(官网解释)
监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。
提醒(Notification):当被监控的某个 Redis出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作,它会将失效Master的其中一个Slave升级为新的Master, 并让失效Master的其他Slave改为复制新的Master; 当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用Master代替失效Master。
(1)哨兵启动后会读取配置文件确定监控的主数据库
(2)启动后,哨兵会与监控的主数据库建立两条连接,一条是连接用来订阅主数据的_sentinel_:hello频道以获取其他同样监控该数据库的哨兵节点的信息。另一条是
1)每10s哨兵会向主数据库和从数据库发送INFO命令
2)每2秒哨兵会向主数据库和从数据库的_sentinel_:hello频道发送自己的信息
3)每1S哨兵会向主数据库,从数据库和其他哨兵发送PING命令
Redis Sentinel 是一个分布式系统, 你可以在一个架构中运行多个 Sentinel 进程(progress), 这些进程使用流言协议(gossip protocols)来接收关于主服务器是否下线的信息, 并使用投票协议(agreement protocols)来决定是否执行自动故障迁移, 以及选择哪个从服务器作为新的主服务器。
虽然 Redis Sentinel 释出为一个单独的可执行文件 redis-sentinel , 但实际上它只是一个运行在特殊模式下的 Redis 服务器, 你可以在启动一个普通 Redis 服务器时通过给定 –sentinel 选项来启动 Redis Sentinel 。
以上是官网上对reids sentinel 的解释,我接下来做一点补充:
gossip protocols:
gossip协议包含多种消息,包括ping,pong,meet,fail等等。
meet:某个节点发送meet给新加入的节点,让新节点加入集群中,然后新节点就会开始与其他节点进行通信,不需要发送形成网络的所需的所有CLUSTER MEET命令。发送CLUSTER MEET消息以便每个节点能够达到其他每个节点只需通过一条已知的节点链就够了。由于在心跳包中会交换gossip信息,将会创建节点间缺失的链接。
ping:每个节点都会频繁给其他节点发送ping,其中包含自己的状态还有自己维护的集群元数据,互相通过ping交换元数据;
pong: 返回ping和meet,包含自己的状态和其他信息,也可以用于信息广播和更新;
fail: 某个节点判断另一个节点fail之后,就发送fail给其他节点,通知其他节点,指定的节点宕机了。
接下来以新增节点为例子,来解释下gossip协议是怎么运作的。
首先,我们有A,B,C三个节点,新增一个D节点,client 命令A 发送meet指令给 D(client 会给A D的ip 和port,刚开始的时候没有名字,暂时以一个随机串当做D的名字,会在之后D的pong补充),然后A会把D放到自己的集群节点列表里面,D节点收到A的meet指令(其中还包括自己维护的集群元数据),将A,B,C存到自己的集群节点列表中,返回pong指令,握手成功。之后A会向B,C发送ping命令,之后B,C就认识了D。
为了使给定的节点能将另一个节点接收到组成 Redis Cluster 的节点列表中,这里只有两种方法:
-
系统管理员发送一个
CLUSTER MEET
命令强制一个节点去会面另一个节点。 -
一个已知的节点发送一个保存在 gossip 部分的节点列表,包含着未知的节点。如果接收的节点已经将发送节点信任为已知节点,它会处理 gossip 部分并且发送一个握手消息给未知的节点。
Redis集群中的每个节点,每隔一段时间就会向其他节点发送心跳包,心跳包中除了包含自己的信息之外,还会包含若干我认识的其他节点的信息。
心跳机制和下线通知
集群中的每个节点,每隔一段时间就会向其他节点发送PING包,节点收到PING包之后,就会回复PONG包。PING包和PONG包具有相同的格式,通过包头的type字段区分类型。因此,将PING和PONG包都称为心跳包。
节点每隔1秒钟,都会从集群节点列表 中随机选取一个节点发送ping。而且,还会轮训字典中的所有节点,如果已经超过 NODE_TIMEOUT/2的时间,没有向该节点发送过PING包了,则会立即向该节点发送PING包。
下线检测
Redis集群节点是通过某个节点是否能及时回复PING包来判断该节点是否下线的。这里的下线包括两种状态:疑似下线(PFAIL)和下线(FAIL)。
如果当前节点已经长时间没有收到节点A对于PING包的回复了,就会将节点A标记为疑似下线。因此所谓疑似下线,就是仅从当前节点的视角来看,节点A已经不可达了。但是节点A是否真正的下线了,还需要征求其他节点的意见。
节点间交互的心跳包中,在其gossip部分会带有节点的状态信息,如果当前节点在收到的其他节点发来的心跳包中,有大多数节点都把节点A标记为PFAIL了,则当前节点就会认为节点A确实下线了,就将其标记为FAIL,表示该节点A确实下线。一旦将A标记为FAIL后,当前节点就会立即通过FAIL包,将节点A下线的消息广播给其他所有节点,这样最终所有节点都会标记节点A为FAIL状态了。