五、多机数据库
这个部分主要介绍跟多级数据库有关的复制、集群、sentinel。
复制功能
源码参见:replication.c
在Redis中可以使用SLAVEOF或者设置slaveof选项,使得一个服务器去复制另一个服务器。这种情形就是我们熟知的主从结构,一般用作读写分离,主服务器是负责读/写,从服务器负责读见下图。
新旧版本的复制对比
在Redis2.8版本之后的复制功能效率更高,安全系数更好,新旧版本复制功能对比如下(请点击或下载查看大图):
其中,旧版本的同步操作如下图所示:
注:在主服务器进行BGSAVE和发送RDB文件的时候,会将所有写命令写入发送缓冲区,在传输完毕之后将所有写命令发送给从服务器。
一个展示命令传播的示例如下图所示:
新版复制功能的部分同步如下图所示:
新版复制功能调用流程图如下:
进一步解释新版复制功能实现部分重同步的原理:
·服务器ID:当从服务器对某一服务器进行了同步操作时,该ID被设置为主服务器的ID。这是为了在从服务器断线重连主服务器时,判断上次所连接的是否是原来的服务器!
·复制偏移量:类似于TCP的SEQ,主从服务器都维护了一个复制偏移量offset:当主服务器给从服务器发送**N个字节(而不是命令)**时,该offset+N;当从服务器接收N个字节时,该Offset+N;这是实现部分同步的关键:让主服务器知道从服务器还差哪些命令没有获取!
·复制积压缓冲区:是主服务器端的一个固定长度(可调整,默认1M)的先进先出队列。这也是部分同步的关键:在该队列中,维护了复制偏移量offset与每一条写命令的对应关系,见下图。
如果从服务器需要的复制命令在该队列中,那么执行部分重同步即可;如果不在···那就只能完全重同步了!
复制的全过程
·设置主服务器的地址端口
·建立套接字连接
·发送PING命令(检查主服务器状态)
·进行身份验证(若设置了masterauth)
·发送端口信息,即从服务器将自身端口发送给主服务器(主要是为了打印信息)
·同步操作(在这个时候两者互为客户端,才可以进行写命令的传输)
·命令传播
在该阶段,从服务器会默认1s的时间给主服务器发送命令 REPLCONF ACK ,这是一种心跳检测,主要是为了检查网络连接或是否有命令丢失。
哨兵Sentinel
源码参见:sentinel.c
介绍
sentinal,哨兵是Redis多机架构中高可用性非常重要的一个组件,主要功能如下:
(1)集群监控,负责监控redis master和slave进程是否正常工作(心跳检测);
(2)消息通知,如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员;
(3)故障转移,如果master node挂掉了,会自动转移到slave node上;
(4)配置中心,如果故障转移发生了,通知client客户端新的master地址;
哨兵本身也是分布式的,作为一个哨兵集群去运行,互相协同工作
(1)故障转移时,判断一个master node是宕机了,需要**大部分(超过一半)**的哨兵都同意才行,涉及到了分布式选举的问题;
(2)即使部分哨兵节点挂掉了,哨兵集群还是能正常工作的,因为如果一个作为高可用机制重要组成部分的故障转移系统本身是单点的,那就很不稳定了;
下面几幅图展示sentinel系统是如何实现监视Redis服务器的:
初始状态如下:
主服务器下线:
执行故障转移:
原主服务器上线并降级
Redis源码、面试指南(5)多机数据库、复制、哨兵、集群(下):https://developer.aliyun.com/article/1508249