关于后端:Redis主从复制Sentinel集群总结

3次阅读

共计 1999 个字符,预计需要花费 5 分钟才能阅读完成。

本文记录学习《Redis 设计与实现》一书中第三局部对于主从复制、Sentinel、集群的常识总结及了解。

一、主从复制

单节点部署,一旦节点产生故障,就会导致服务不可用,主 - 从集群就是为了解决这类问题,进步可用性,同时通过主从进行读写拆散,能够缩小主库的读压力。

主从复制蕴含全量复制、基于长链接的命令流传、增量复制。

当从节点执行 slaveof ip port 后,建设主从关系后,会进行第一次全量复制,如下:

1、第一次全量同步,master 节点开启 bgsave 子过程来创立全量 RDB,并发送给从节点,;

2、从节点接管到主节点的 RDB 文件,革除本地数据后加载 RDB 文件;

2、命令流传,全量同步的过程中产生的写命令会缓存在复制缓冲区(replication buffer),主节点将复制缓冲区内的写命令发给从节点执行。

主从节点网络断开 - 增量复制

在 2.8 版本之前,主从节点网络断开后会进行全量复制,效率低下。

从 2.8 开始,网络断开后从新连贯,主从节点会进行增量复制。

当主从节点断开连接后,从新连贯上后,会依据主从节点的偏移量从 repl_backlog_buffer 缓冲区获取写命令进行增量同步。

全量复制为什么用 RDB,不必 AOF?

1、RDB 文件内容是通过压缩的二进制数据,而 AOF 文件记录的是每一次写操作的命令,写操作越多文件会变得很大,其中还包含很多对同一个 key 的屡次冗余操作,应用 RDB 文件传输绝对 AOF 文件会缩小网络耗费;

2、从库通过 RDB 快照加载数据要快,AOF 要逐条执行命令;

二、哨兵机制

哨兵节点是一个非凡的 Redis 实例,非凡在于一般 Redis 节点相比,命令集不同,哨兵节点不能执行数据操作命令,能够执行 PING,INFO 等命令。哨兵集群的作用是用来监控 Redis 集群,对产生故障的 master 节点能进行故障转移,保障高可用。

哨兵节点会与所有 Redis 主 - 从节点创立两个连贯,一个是订阅_sentinel:hello 频道;一个是命令连贯。

主观下线 vs 主观下线

哨兵会每隔一秒向 Redis 节点(主、从)发送 ping 命令,依据节点的响应分为:

  • 无效响应:在规定的工夫(通过 down-after-milliseconds 设置)内,响应 +PONG、-LOADING、-MASTERDOWN,即为无效响应
  • 有效响应:除了下面三种响应或在规定的工夫内未响应,即为有效响应

如果未有效响应,则会被哨兵标记为主观下线。

当哨兵将一个主节点判断为主观下线后,为了确认该节点是否为主观下线,会向其余监控这一节点的哨兵进行询问,发送 is-master-down-by-addr 命令,当收到所有的回复中,有大于等于 quonum 个哨兵判断此主节点为主观下线,即可判断此主节点为主观下线。

在断定主节点为主观下线后,哨兵集群会选举领头的哨兵(通过 Raft 算法选举,此处不开展),领头的哨兵随后进行故障转移。

三、集群

Redis 节点通过 cluster meet 命令实现节点间握手,建设连贯。建设连贯后,节点间会定时相互发送 ping/pong 命令,替换数据信息(节点信息、状态等)。

每个 Redis 节点都有一个 clusterNode 来保留节点信息,当节点退出集群中时会有个 clusterState 构造来保留集群的信息状态,如下图所示:

节点间通过 cluster meet 命令,在连贯过程中会去更新 clusterState 中的 nodes 信息。

集群的整个数据库被分为 16384 个槽,每个节点负责的槽能够通过 cluster addslots 来进行指派。在 clusterNode 构造中属性 slots 记录节点负责哪些槽:

struct clusterNode {unsigned char slots[16384/8];
    int numslots;
}

同时,clusterState 构造里会存 16384 个槽的指派信息,如下:

struct clusterState {clusterNode *slots[16384];
}

通过 clusterState 的 slots 能够通过 O(1)工夫找到某个槽对应的节点。

在集群中执行命令

在集群环境下,客户端向某节点发送数据库命令时,会首先计算 key 属于哪个槽,如果槽对应的指派是以后节点,会执行命令;如果槽对应的指标不是以后节点,会返回 MOVED 给客户端,并返回槽对应指派的节点信息,后再次执行命令。

计算 key 属于哪个槽:CRC16(key) & 16383

为什么是 16384 个槽?

  • 节点之间检测状态,发送的数据里蕴含节点的分槽信息数组 slots[16383/8],如果槽太多会导致每次传输的数据包增大,因为节点间的检测时很频繁的,会影响传输效率,容易造成网络阻塞
  • 一般来说 Redis 的集群节点数不倡议超过 1000 个,16384 个槽位足够用

四、参考

  • 《Redis 设计与实现》
  • https://www.cnblogs.com/rjzheng/p/11430592.html
正文完
 0