一、主从复制概念
互联网“三高”架构:高并发、高性能、高可用
高可用就是5个9
为了避免单点redis服务器故障,准备多台服务器,互相连通。将数据复制多个副本保存在不同的服务器上,连接在一起,并保证数据是同步的,即使有其中一台服务器宕机,其他服务器依然可以继续提供服务,实现Redis的高可用,同时实现数据冗余备份
多台服务器连接方案
- master:主服务器,主节点,主库,提供数据,一般负责客户端的写数据操作(客户端的写操作少)
- slave:从服务器,从节点,从库,接受数据,定期同步master中的数据,负责客户端的读数据操作(客户端的读操作多)
- 主从复制特征:一个master可以拥有多个slave,一个slave只对应一个master
二、高可用的集群方案
假如此时一台slave故障,其他的slave可以对外提供读数据服务,当故障的slave恢复后,也可以从master进行数据恢复
假如此时master故障,我们会选择一台slave作为新的master对外提供写数据服务,以及和slave进行主从复制
此外,为了防止master宕机引发问题,我们还可以使用master集群
当master压力很大时,我们可以使用多级master用于分担压力(这会导致一些问题,需要使用哨兵解决)
主从复制作用
- 读写分离:master写、slave读,提高服务器的读写负载能力
- 负载均衡:基于主从结构,配合读写分离,由slave分担master负载,并根据需求的变化,改变slave的数量,通过多个从节点分担数据读取负载,大大提高Redis服务器并发量与数据吞吐量
- 故障恢复:当master出现问题时,由slave提供服务,实现快速的故障恢复
- 数据冗余:实现数据热备份,是持久化之外的一种数据冗余方式
- 高可用基石:基于主从复制,构建哨兵模式与集群,实现Redis的高可用方案
三、主从复制工作流程概述
主从复制过程大体可以分为3个阶段:建立连接阶段(即准备阶段),数据同步阶段(初始化slave的数据),命令传播阶段(slave执行和master相同的写操作)
四、阶段一:建立连接阶段
建立slave到master的连接,使master能够识别slave,master保存slave的port,slave保存master的ip:port
方式一:客户端发送命令(客户端连接服务器后,操作一台服务器成为另一台服务器的slave)
slaveof <masterip><masterport>
方式二:启动服务器参数(不用客户端连接服务器,服务器启动时直接连接另一台服务器,并成为其slave)
redis-server --slaveof <masterip><masterport>
方式三:服务器配置
slaveof <masterip><masterport>
1. 用客户端操作,实现主从复制(命令方式)
修改使用6379端口和6380端口启动的配置文件,设置为前台启动,不使用日志文件,日志打印到前台
在6379和6380端口启动redis服务
登录6380的redis服务器,使用slaveof使6380成为6379的slave
6380这边多了一些日志信息,说明连接6379成功,且成为了6379的slave
6379这边也多了一些日志信息,表示建立连接成功且数据同步成功了
使用客户端连接作为master的6379服务器,进行写操作
在连接到6380客户端这边获取key,虽然是在6379服务器写的数据,由于进行了主从复制,6380这边依然可以获取
2. 服务器启动时,直接另一台服务器的成为slave,实现主从复制(命令方式)
6380成功成为6379的slave
3. 配置文件方式实现主从复制
上述两种使用命令的方式,实现主从复制都不是主流,最多的还是使用配置文件
修改配置文件
使用修改后的配置文件启动redis服务
连接成功
6379进行写操作
由于配置了主从复制,6380同步了6379的数据,成功获取key
输入info,查看msater相关信息
输入info,查看slave相关信息
4. 断开主从复制
slaveof no one # slave客户端发送,与master断开连接
slave客户端发送命令
master客户端修改name
slave并没有进行同步,说明很主从复制已经断开了
5. 设置权限校验
- master客户端发送命令设置密码(一旦设置了密码,客户端访问就必须带上密码)
config set requirepass <password>
- master配置文件设置密码
config set requirepass <password> config get requirepass
- slave客户端发送命令设置密码
auth <password>
- slave配置文件设置密码
masterauth <password>
- slave启动服务器设置密码
redis-server –a <password>
五、阶段二:数据同步阶段
在slave初次连接master后,同步master中的所有数据到slave,将slave的数据库状态更新成master当前数据库状态
全量复制: 用RDB的方式同步master中的大量数据,slave拿到的是数据,恢复速度快
部分复制: master执行bgsave生成RDB文件过程中收到的客户端的指令会保存在一个缓冲区,用AOF的方式记录并发送给slave,slave收到AOF文件后会进行bgrewriteaof,然后再执行AOF文件中的指令
同步完成的最终状态: slave具有master端全部数据,包含RDB过程接收的数据;而master则保存slave当前数据同步的位置
数据同步阶段master说明
- 如果master数据量巨大,数据同步阶段应避开流量高峰期,避免造成master阻塞,影响业务正常执行
- 复制缓冲区大小设定不合理,会导致数据溢出。如果进行全量复制周期太长,进行部分复制时发现数据已经存在丢失的情况,必须进行第二次全量复制,致使slave陷入死循环状态
- master单机内存占用主机内存的比例不应过大,建议使用50%-70%的内存,留下30%-50%的内存用于执行bgsave命令和创建复制缓冲区
repl-backlog-size 1mb # 修改复制缓冲区大小
数据同步阶段slave说明
- 为避免slave进行全量复制、部分复制时服务器响应阻塞或数据不同步,建议关闭数据同步阶段的对外服务
slave-serve-stale-data yes|no
- 数据同步阶段,master发送给slave信息可以理解master是slave的一个客户端,主动向slave发送命令
- 多个slave同时对master请求数据同步,master发送的RDB文件增多,会对带宽造成巨大冲击,如果master带宽不足,因此数据同步需要根据业务需求,适量错峰
- slave过多时,建议调整拓扑结构,由一主多从结构变为树状结构,中间的节点既是master,也是slave。注意使用树状结构时,由于层级深度,导致深度越高的slave与最顶层master间数据同步延迟较大,数据一致性变差,应谨慎选择
六、阶段三:命令传播阶段
当master数据库状态被修改后,导致主从服务器数据库状态不一致,此时需要让主从数据同步到一致的状态,同步的动作成为命令传播
master将收到的写命令发送给slave,slave收到后执行命令
命令传播阶段如果出现了断网的现象,短时间网络中断需要进行部分复制,长时间网络中断则进行全量复制
部分复制的三个要素:服务器的运行id (run_id)、主服务器的复制积压缓冲区、主从服务器的复制偏移量
1. 服务器的运行id (run_id)
- 概念: 服务器运行ID是每一台服务器每次运行的身份识别码,一台服务器多次运行可以生成多个运行id
- 组成: 运行id由40位字符组成,是一个随机的十六进制字符,例如:fdc9ff13b9bbaab28db42b3d50f852bb5e3fcdce
- 作用: 运行id被用于在服务器间进行传输,识别身份,如果想两次操作均对同一台服务器进行,必须每次操作都携带对应的运行id,用于对方识别
- 实现方式: run_id在每台服务器启动时自动生成的,master在首次连接slave时,会将自己的运行ID发送给slave,slave保存此ID,通过
info Server
命令,可以查看节点的run_id
2. 主服务器的复制积压缓冲区
为了解决由于突发原因(网络不通等…),只有部分slave同步了master的数据的问题,redis需要使用一个复制积压缓冲区
- 复制积压缓冲区: 是一个先进先出(FIFO)的队列,用于存储服务器执行过的命令,每次传播命令,master都会将传播的命令记录下来,并存储在复制缓冲区。默认存储空间大小是1M(可配置),由于存储空间大小是固定的,当入队元素的数量大于队列长度时,最先入队的元素会被弹出,而新元素会被放入队列
- 由来: 每台服务器启动时,如果开启有AOF或被链接成为master节点,即创建复制缓冲区
- 作用: 用来保存master收到的所有指令(仅影响数据变更的指令,例如set、select)
- 数据来源: 当master接收到主客户端的指令时,除了将指令执行,会将该指令存储到缓冲区中
复制积压缓冲区工作原理
一条指令会被解析成AOF格式,然后存入复制积压缓冲区
master记录给不同slave发送的信息对应的offset,slave记录已接收的信息对应的offset,通过offset区分不同的slave当前数据传播的差异
3. 主从服务器的复制偏移量offset
- 概念: 一个数字,描述复制缓冲区中的位置
- 作用: 同步信息,对比master与slave的差异,当slave断线后,恢复数据使用
master需要记录给多个slave发送数据对应的位置(多个),发送一次记录一次;slave需要记录master发送过来的数据对应的位置(一个),接收一次记录一次
七、数据同步和命令传播阶段工作流程
八、心跳机制
进入命令传播阶段后,master与slave间需要进行数据同步,使用心跳机制进行通信,同时保持双方连接在线
master心跳: 只是ping一下slave,判断slave是否在线,周期由repl-ping-slave-period决定,默认10秒。可通过INFO replication
获取slave最后一次连接时间间隔,lag项维持在0或1视为正常,否则心跳异常
slave心跳: slave 每秒发送一次REPLCONF ACK {offset}
,汇报slave自己的复制offset,获取最新的数据变更指令,同时判断master是否在线
当很多的slave离线或延迟过高时,master为保障数据稳定性,将拒绝所有数据同步操作;slave数量少于2个或所有slave延迟都大于等于10s时,强制关闭master写功能,停止数据同步
min-slave-to-write 2 # 设置最少的slave数量,少于这个值则强制关闭master写功能,停止数据同步 min-slave-max-lag 10 # 设置slave最大的延迟,少于这个值则强制关闭master写功能,停止数据同步
slave数量和延迟由slave发送REPLCONF ACK命令做确认
九、主从复制常见问题
1. 频繁的全量复制
2. 频繁的网络中断
3. 数据不一致