Redis主从复制 - 实现原理

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
日志服务 SLS,月写入数据量 50GB 1个月
简介: 有3种配置方式:(1)配置文件在从服务器的配置文件中加入:slaveof <masterip> <masterport>(2)启动命令redis-server启动命令后加入 --slaveof <masterip> <masterport>(3)客户端命令Redis服务器启动后,直接通过客户端执行命令:slaveof <masterip> <masterport>,则该Redis实例成为从节点。

参考资料

作者搭建记录:https://github.com/mailjobblog/dev_redis/tree/master/master_slave

redis中国区文档:http://redis.cn/topics/replication.html

redis-GitHub(可下载redis.conf和sentinel.conf):https://github.com/redis/redis

redis 官网配置文件:https://redis.io/topics/config

优秀文章:https://www.cnblogs.com/kismetv/p/9236731.html

如何搭建

搭建命令

需要注意,主从复制的开启,完全是在从节点发起的;不需要我们在主节点做任何事情。

有3种配置方式:

(1)配置文件
在从服务器的配置文件中加入:slaveof <masterip> <masterport>

(2)启动命令
redis-server启动命令后加入 --slaveof <masterip> <masterport>

(3)客户端命令
Redis服务器启动后,直接通过客户端执行命令:slaveof <masterip> <masterport>,则该Redis实例成为从节点。


密码验证,如果主节点的redis设置了密码,需要加入以下参数验证主节点的密码

(1)配置文件
masterauth <password>
(2)客户端命令
config set requirepass <password>

查看节点配置信息
127.0.0.1:6379 >> info replication

名次解释
masterip:主节点redis的ip
masterport:主节点redis的端口
master:主节点
slave:从节点

注意点:
搭建完成后,要用  info replication 查看配置是否成功
若用docker的话, run的时候记得要指定数据卷
docker的几个容器要在同一个网桥上面

实现原理

全量同步

Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下:

1)从服务器连接主服务器,发送SYNC命令;

2)主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;

3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;

4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;

5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;

6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;

img

完成上面几个步骤后就完成了从服务器数据初始化的所有操作,从服务器此时可以接收来自用户的读请求。

增量同步演示步骤

1、从节点执行slaveof 主节点host 主节点port命令后,在redis会打印如下所示的日志信息:

 * REPLICAOF 192.168.216.129:6379 enabled (user request from 'id=4 addr=127.0.0.1:58476 fd=9 name= age=142 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=49 qbuf-free=32719 argv-mem=26 obl=0 oll=0 omem=0 tot-mem=61490 events=r cmd=slaveof use
r=default')

slaveof是异步命令,执行完该命令后从节点保存主节点的host和port信息,但是并未真正开始复制;

2、创建socket连接,从节点内部定时每秒执行一次复制定时函数replicationCron,当发现存在可以连接主节点时就会根据主节点的信息创建socket连接,如果节点无法连接就会无限重试或者直到执行slaveof no one命令,此时redis会打印如下所示日志:

* Connecting to MASTER 192.168.216.129:6379
* MASTER <-> REPLICA sync started

此时主节点会给从节点的socket连接创建客户端状态并将其当作主节点上的一个客户端,使用client list命令是可以明确看到这个客户端的,如下所示:
img

3、从节点发送ping命令,等待主节点回复pong,用以检测socket是否可用以及主节点是否可接受处理命令,如果从节点接收响应超时或者接受到pong以外的响应,从节点就会断开复制链接,等待下次定时任务时再发起重连,日志如下:

* Master replied to PING, replication can continue...

4、masterauth验证,如果主节点设置了密码,那么此时需要验证密码才可以进行下一步操作,密码验证失败的话会断开连接,等待下一次重连;

5、数据同步,数据同步其实就是从节点的初始化的过程,数据同步包含全量同步以及部分同步,同步的过程后面具体分析,另外要注意一点的是在数据同步阶段主节点需要主动向从节点发送请求,因此此时主从节点互为客户端,数据同步对应的日志如下所示:

* Trying a partial resynchronization (request 6c4167e7160b6bb316de536f24a93b1f260b2f10:1).
* Full resync from master: ac0f31e4a32d99d77c2007009c312868023713a9:840612
* Discarding previously cached master state.
* MASTER <-> REPLICA sync: receiving 269 bytes from master to disk
* MASTER <-> REPLICA sync: Flushing old data
* MASTER <-> REPLICA sync: Loading DB in memory
* Loading RDB produced by version 6.0.9
* RDB age 0 seconds
* RDB memory usage when created 1.85 Mb
* MASTER <-> REPLICA sync: Finished with success

6、持续性复制,经过前面五个步骤,正常情况下主从已经创建成功,之后主节点会源源不断的将写命令发送到从节点,从而保证主从一致性

增量同步

Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。

增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。

Redis主从同步策略

主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。

增量同步实现

1)从服务器向主服务器发送PSYNC命令,携带主服务器的runid和复制偏移量;

2)主服务器验证runid和自身runid是否一致,如不一致,则进行全量复制;

3)主服务器验证复制偏移量是否在积压缓冲区内,如不在,则进行全量复制;

4)如都验证通过,则主服务器将保持在积压区内的偏移量后的所有数据发送给从服务器,主从服务器再次回到一致状态。

注意点

如果多个Slave断线了,需要重启的时候,因为只要Slave启动,就会发送sync请求和主机全量同步,当多个同时出现的时候,可能会导致Master IO剧增宕机。

存在问题

1、复制风暴

产生原因:

当从服务器大量宕机之后,又同时启动。这个时候,从服务器同时去同步主服务器的redis,这个时候会产生大量的并发,导致主服务器宕机发生

解决方案:

1、采用下方图示方案解决,一部分从节点挂到一些从节点上面。这个时候从库同步到主库的redis后,其他从库再从这个从库同步

2、采用多个主节点策略,就是多个master节点,这个就牵扯到了redis集群策略了

img

2、主从数据不同步

产生原因: 由于主库和从库的同步有一个过程,所以可能产生master库某些写入的数据,slave 短暂的读不到

如何解决

1、如果这个数据不是很急的话,可以逻辑层面可以做一个延迟策略

2、如果你必须想要读取到这个数据,有这么几个办法:

3、 可以对slave的偏移量值进行监控,如果发现某台slave的偏移量有问题,则将数据读取操作切换到master,但本身这个监控开销比较高

3、读到过期数据(脏数据)

产生原因: redis在删除过期key的时候,是有两种策略,第一种是懒惰型策略,即只有当redis操作这个key的时候,发现这个key过期,就会把这个key删除。第二种是定期采样一些key进行删除

redis主从同步配置中,我们知道,redis里master和slave达成一种协议,slave是不能处理数据的(即不能删除数据)而我们的客户端没有及时读到到过期数据同步给master将key删除,就会导致slave读到过期的数据

如何解决

这个问题已经在redis3.2版本中解决

4、数据延迟造成的脏数据

产生原因: master会异步的将数据复制到slave,如果这是slave发生阻塞,则会延迟master数据的写命令,造成数据不一致的情况

解决方案

可以对slave的偏移量值进行监控,如果发现某台slave的偏移量有问题,则将数据读取操作切换到master

5、主从配置不一致

这个问题一般很少见,但如果有,就会发生很多诡异的问题

例如:

1. maxmemory配置不一致:这个会导致数据的丢失

原因:例如master配置4G,slave配置2G,这个时候主从复制可以成功,但,如果在进行某一次全量复制的时候,slave拿到master的RDB加载数据时发现自身的2G内存不够用,这时就会触发slave的maxmemory策略,将数据进行淘汰。更可怕的是,在高可用的集群环境下,如果我们将这台slave升级成master的时候,就会发现数据已经丢失了。

2. 数据结构优化参数不一致(例如hash-max-ziplist-entries):这个就会导致内存不一致

原因:例如在master上对这个参数进行了优化,而在slave没有配置,就会造成主从节点内存不一致的诡异问题。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4月前
|
NoSQL Redis
Redis 执行 Lua保证原子性原理
Redis 执行 Lua 保证原子性原理
416 1
|
4月前
|
监控 NoSQL Redis
看完这篇就能弄懂Redis的集群的原理了
看完这篇就能弄懂Redis的集群的原理了
157 0
|
3月前
|
缓存 NoSQL Linux
redis的原理(三)
redis的原理(三)
redis的原理(三)
|
2月前
|
存储 NoSQL 大数据
大数据-51 Redis 高可用方案CAP-AP 主从复制 一主一从 全量和增量同步 哨兵模式 docker-compose测试
大数据-51 Redis 高可用方案CAP-AP 主从复制 一主一从 全量和增量同步 哨兵模式 docker-compose测试
41 3
|
2月前
|
设计模式 NoSQL 网络协议
大数据-48 Redis 通信协议原理RESP 事件处理机制原理 文件事件 时间事件 Reactor多路复用
大数据-48 Redis 通信协议原理RESP 事件处理机制原理 文件事件 时间事件 Reactor多路复用
44 2
|
2月前
|
存储 缓存 NoSQL
大数据-46 Redis 持久化 RDB AOF 配置参数 混合模式 具体原理 触发方式 优点与缺点
大数据-46 Redis 持久化 RDB AOF 配置参数 混合模式 具体原理 触发方式 优点与缺点
71 1
|
2月前
|
NoSQL 关系型数据库 MySQL
Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习
本文全面阐述了Redis事务的特性、原理、具体命令操作,指出Redis事务具有原子性但不保证一致性、持久性和隔离性,并解释了Redis事务的适用场景和WATCH命令的乐观锁机制。
373 0
Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习
|
3月前
|
存储 缓存 NoSQL
redis的原理(四)
redis的原理(四)
|
3月前
|
存储 缓存 NoSQL
redis的原理(二)
redis的原理(二)
|
3月前
|
缓存 NoSQL 安全
Redis的原理(一)
Redis的原理(一)
下一篇
DataWorks