六、redis主从同步

参考Redis 的主从同步,及两种高可用方式
010.Redis 主从架构搭建及原理详解

一、介绍

1、简介

redis的主从就是多台redis的数据保持一致。redis主服务器可写入和读取,从服务器只读。redis第一次同步的时候,redis主服务器生成一个rdb文件同步到从,从服务器加载到内存。
Redis的主从结构可以采用一主多从或者级联结构,Redis主从复制可以根据是否是全量分为全量同步和增量同步。

2、全量同步

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

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

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

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

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

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

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

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

注意:

  • 如果节点间网络通信不好,那么当从节点同步的速度不如主节点接收新写请求的速度时,buffer 中会丢失一部分指令,从节点中的数据将与主节点中的数据不一致,此时将会触发快照同步。

  • 快照同步(这里快照同步是rbd文件同步)是一个非常耗费资源的操作,它首先需要在主节点上进行一次 bgsave 将当前内存的数据全部快照到RDB文件中,然后再将快照文件的内容全部传送到从节点。从节点将RDB文件接受完毕后,立即执行一次全量加载,加载之前先要将当前内存的数据清空。加载完毕后通知主节点继续进行增量同步。

  • 在整个快照同步进行的过程中,主节点的复制 buffer 还在不停的往前移动,如果快照同步的时间过长或者复制 buffer 太小,都会导致同步期间的增量指令在复制 buffer 中被覆盖,这样就会导致快照同步完成后无法进行增量复制,然后会再次发起快照同步,如此极有可能会陷入快照同步的死循环。所以需要配置一个合适的复制 buffer 大小参数,避免快照复制的死循环。

3、增量同步

(1)、Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。 增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。
(2)、redis 同步的是指令流,主节点会将那些对自己的状态产生修改性影响的指令记录在本地的内存 buffer 中,然后异步将 buffer 中的指令同步到从节点,从节点一边执行同步的指令流来达到和主节点一样的状态,一边向主节点反馈自己同步到哪里了 (偏移量,这是redis-2.8之后才有的特性)。从节点同步数据的时候不会影响主节点的正常工作,也不会影响自己对外提供读服务的功能,从节点会用旧的数据来提供服务,当同步完成后,需要删除旧数据集,加载新数据,这个时候才会暂停对外服务。
(3)、因为内存的 buffer 是有限的,所以 redis 主节点不能将所有的指令都记录在内存 buffer 中。redis 的复制内存 buffer 是一个定长的环形数组,如果数组内容满了,就会从头开始覆盖前面的内容。
在这里插入图片描述

4、Redis主从同步策略

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

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

5、主从复制特点

* 主数据库可以进行读写操作,当读写操作导致数据变化时会自动将数据同步给从数据库

* 从数据库一般都是只读的,并且接收主数据库同步过来的数据

* 一个master可以拥有多个slave,但是一个slave只能对应一个master

* slave挂了不影响其他slave的读和master的读和写,重新启动后会将数据从master同步过来

* master挂了以后,不影响slave的读,但redis不再提供写服务,master重启后redis将重新对外提供写服务

* master挂了以后,不会在slave节点中重新选一个master

二、主从同步的详细流程

  • 1、在从节点的配置文件中的slaveof配置项中配置了主节点的IP和port后,从节点就知道自己要和那个主节点进行连接了。

  • 2、从节点内部有个定时任务,会每秒检查自己要连接的主节点是否上线,如果发现了主节点上线,就跟主节点进行网络连接。注意,此时仅仅是取得连接,还没有进行主从数据同步。

  • 3、从节点发送ping命令给主节点进行连接,如果设置了口令认证(主节点设置了requirepass),那么从节点必须发送正确的口令(masterauth)进行认证。

  • 4、主从节点连接成功后,主从节点进行一次快照同步。事实上,是否进行快照同步需要判断主节点的run id,当从节点发现已经连接过某个run id的主节点,那么视此次连接为重新连接,就不会进行快照同步。相同IP和port的主节点每次重启服务都会生成一个新的run id,所以每次主节点重启服务都会进行一次快照同步,如果想重启主节点服务而不改变run id,使用redis-cli debug reload命令。

  • 5、当开始进行快照同步后,主节点在本地生成一份rdb快照文件,并将这个rdb文件发送给从节点,如果复制时间超过60秒(配置项:repl-timeout),那么就会认为复制失败,如果数据量比较大,要适当调大这个参数的值。主从节点进行快照同步的时候,主节点会把接收到的新请求命令写在缓存 buffer 中,当快照同步完成后,再把 buffer 中的指令增量同步到从节点。如果在快照同步期间,内存缓冲区大小超过256MB,或者超过64MB的状态持续时间超过60s(配置项:client-output-buffer-limit slave 256MB 64MB 60),那么也会认为快照同步失败。

  • 6、从节点接收到RDB文件之后,清空自己的旧数据,然后重新加载RDB到自己的内存中,在这个过程中基于旧的数据对外提供服务。如果主节点开启了AOF,那么在快照同步结束后会立即执行BGREWRITEAOF,重写AOF文件。

  • 7、主节点维护了一个backlog文件,默认是1MB大小,主节点向从节点发送全量数据(RDB文件)时,也会同步往backlog中写,这样当发送全量数据这个过程意外中断后,从backlog文件中可以得知数据有哪些是发送成功了,哪些还没有发送,然后当主从节点再次连接后,从失败的地方开始增量同步。这里需要注意的是,当快照同步连接中断后,主从节点再次连接并非是第一次连接,所以进行增量同步,而不是继续进行快照同步。

  • 8、快照同步完成后,主节点后续接收到写请求导致数据变化后,将和从节点进行增量同步,遇到 buffer 溢出则再触发快照同步。

  • 9、主从节点都会维护一个offset,随着主节点的数据变化以及主从同步的进行,主从节点会不断累加自己维护的offset,从节点每秒都会上报自己的offset给主节点,主节点也会保存每个从节点的offset,这样主从节点就能知道互相之间的数据一致性情况。从节点发送psync runid offset命令给主节点从而开始主从同步,主节点会根据自身的情况返回响应信息,可能是FULLRESYNC runid offset触发全量复制,也可能是CONTINUE触发增量复制。

  • 10、主从节点因为网络原因导致断开,当网络接通后,不需要手工干预,可以自动重新连接。

  • 11、主节点如果发现有多个从节点连接,在快照同步过程中仅仅会生成一个RDB文件,用一份数据服务所有从节点进行快照同步。

  • 12、从节点不会处理过期key,当主节点处理了一个过期key,会模拟一条del命令发送给从节点。

  • 13、主从节点会保持心跳来检测对方是否在线,主节点默认每隔10秒发送一次heartbeat,从节点默认每隔1秒发送一个heartbeat。

  • 14、建议在主节点使用AOF+RDB的持久化方式,并且在主节点定期备份RDB文件,而从节点不要开启AOF机制,原因有两个,一是从节点AOF会降低性能,二是如果主节点数据丢失,主节点数据同步给从节点后,从节点收到了空的数据,如果开启了AOF,会生成空的AOF文件,基于AOF恢复数据后,全部数据就都丢失了,而如果不开启AOF机制,从节点启动后,基于自身的RDB文件恢复数据,这样不至于丢失全部数据。

三、redis主从搭建和测试

在另一台机器上部署一下redis,部署过程看之前的博客一、redis 编译安装嫌麻烦的话也可以复制修改配置文件,然后直接再起一个实例。

1、修改从节点的配置文件

bind 0.0.0.0  #监听地址更改,0.0.0.0代表监控所有网卡
port 6379      #监听端口更改,6379为默认
daemonize yes    #是否后台启动,	Redis 默认不是以守护进程的方式运行,可以通过该配置项修改,使用 yes 启用守护进程(Windows 不支持守护线程的配置为 no )
pidfile "/data/redis/redis.pid"   #pid存放目录 当 Redis 以守护进程方式运行时,Redis 默认会把 pid 写入 /var/run/redis.pid 文件,可以通过 pidfile 指定,这里改为/data/redis/redis.pid
logfile "/data/redis/redis.log"  #日志存放目录 	日志记录方式,默认为标准输出stdout,如果配置 Redis 为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给 /dev/null
dir /data/redis/     #工作目录 指定本地数据库存放目录

#下面部分和主节点不同

slaveof 10.0.0.107 6379 #绑定master的ip和port
slave-read-only yes # 从节点只读
slave-serve-stale-data yes #从节点在处于快照同步期间是否对外提供服务

2、 查看主从同步信息

info Replication

127.0.0.1:6379> info Replication
# Replication
role:slave
master_host:10.0.0.107
master_port:6379
master_link_status:up
master_last_io_seconds_ago:6
master_sync_in_progress:0
slave_repl_offset:126
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:08a975c59c54356156b723d03aeb4cd85ddfa13d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:126
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:112
3、设置主从后,从库只有读权限
127.0.0.1:6379> get name
"wangxiaoyu"
127.0.0.1:6379> set name wangxiaoyu2
(error) READONLY You can't write against a read only slave.
4、往主写入数据,主从数据会保持同步

主节点上写入或修改

127.0.0.1:6379> set name wangxiaoyu2333
OK

从节点上查看

127.0.0.1:6379> get name
"wangxiaoyu2333"
5、主从同步的停止
SLAVEOF no one #在从库上运行
6、加密的主从同步

主从服务器上都执行,也可以直接修改配置文件再重启,requirepass和masterauth主从的配置保持一致,预防主从切换后环境不一致

config set requirepass '123456' #主服务器设置密码,从服务器过段时间就显示为down的状态了
config set masterauth '123456' #从服务器需要设置主从同步的认证密码
config rewrite
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值