快来学Redis | 主从复制的原理及简单验证

Redis 有三种集群模式,第一个就是主从模式,第二种“哨兵”模式,第三种是Cluster集群模式,第三种的集群模式是在 Redis 3.x以后的版本才增加进来的,我们今天就来说一下 Redis 第一种集群模式:主从集群模式。

Redis 主从复制原理


Redis 主从配置比较简单,基本就是在从节点配置文件加上:slaveof 192.168.1.128 6379

主要是通过 master server持久化的 rdb 文件实现的。master server 先 dump 出内存快照文件,然后将 rdb 文件传给 slave server,slave server 根据 rdb 文件重建内存表。

整体过程

初始化:配置好主从后,无论 slave server 是初次还是重新连接到 master server , slave server 都会发送 PSYNC 命令到 master server。 如果是重新连接,且满足增量同步的条件(下面详述),那么 Redis 会将内存缓存队列中的命令发给 slave server ,完成增量同步(Partial resynchronization),否则进行全量同步。

正常同步开始:任何对 master server 的写操作都会以 redis 命令的方式(可以查看 Redis 的 RESP 协议),通过网络发送给 slave server。

Redis 全量复制过程(full resynchronization)

这里写图片描述

  1. slave server 启动连接到 master server 之后,salve server 主动发送SYNC命令给 master server;
  2. master server 接受 SYNC 命令之后,判断是否有正在进行内存快照的子进程,如果有,则等待其结束,否则,fork 一个子进程,子进程把内存数据保存为文件,并发送给 slave server;
  3. master server 子进程做数据快照时,父进程可以继续接收 client 端请求写数据,此时,父进程把新写入的数据放到待发送缓存队列中;
  4. slave server 接收内存快照文件之后,清空内存数据,根据接收的快照文件,重建内存表数据结构;
  5. master server 把快照文件发送完毕之后,发送缓存队列中保存的子进程快照期间改变的数据给 slave server,slave server 做相同处理,保存数据一致性;
  6. master server 后续接收的数据,都会通过步骤1建立的连接,把数据发送到 slave server;

需要注意(Redis 2.8 之前):slave server 如果因为网络或其他原因断开与 master server 的连接,当 slave server 重新连接时,需要重新获取 master server 的内存快照文件,slave server 的数据会自动全部清空,然后再重新建立内存表,这样会让 slave server 启动恢复服务比较慢,同时也给 master server 带来较大压力,可以看出 Redis 的复制没有增量复制的概念,这是 Redis 主从复制的一个主要弊端,在实际环境中,尽量规避中途增加从库。

Redis 2.8 之前不支持增量,到 2.8 之后就支持增量了!


Redis 增量同步过程(partial resynchronization)

增量同步的条件

几个重要概念:

  • 内存缓存队列(in-memory backlog):用于记录连接断开时 master server 收到的写操作
  • 复制偏移量(replication offset):master,slave 都有一个偏移,记录当前同步记录的位置
  • master 服务器 id(master run ID):master server 唯一标识。

现网络连接断开后,slave server 将尝试重连 master server 。当满足下列条件时,重连后会进行增量同步:

  1. slave server 记录的 master 服务器id 和当前要连接的 master 服务器id 相同 ;
  2. slave server 的复制偏移量比 master server 的偏移量靠前。比如 slave server 是1000, master server 是1100;
  3. slave server 的复制偏移量所指定的数据仍然保存在主服务器的内存缓存队列中;
同步过程

确认执行增量同步后,Redis 会将内存缓存队列中的命令通过网络发给 slave server , 完成增量同步。

Redis 主从复制验证


Redis 全量复制过程的验证

环境:

  • master server :192.168.1.128:6379
  • slave server:192.168.1.129:6379

在 master server 先存入一些数据:
这里写图片描述

将 slave server 的日志级别调整为 verbose:
这里写图片描述

设置主从:

在 slave server 执行如下语句:

[root@peipei3514 bin]# ./redis-cli
127.0.0.1:6379> slaveof 192.168.1.128 6379   # 设置 master server
OK
127.0.0.1:6379>

查看日志:

[root@peipei3514 /]# tail -f /usr/local/redis/logs/redis.log
......
1578:S 24 Jun 13:31:49.416 * Before turning into a slave, using my master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.
1578:S 24 Jun 13:31:49.420 * SLAVE OF 192.168.1.128:6379 enabled (user request from 'id=4 addr=127.0.0.1:60734 fd=8 name= age=13 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=slaveof')
1578:S 24 Jun 13:31:49.528 * Connecting to MASTER 192.168.1.128:6379
1578:S 24 Jun 13:31:49.536 * MASTER <-> SLAVE sync started          # 发送 SYNC 命令
1578:S 24 Jun 13:31:49.591 * Non blocking connect for SYNC fired the event.
1578:S 24 Jun 13:31:49.600 * Master replied to PING, replication can continue...
1578:S 24 Jun 13:31:49.620 * Trying a partial resynchronization (request 910f37d9a6d3be1de6341ba6f5f52871419b7c68:1).
1578:S 24 Jun 13:31:49.990 * Full resync from master: 18aca6a0c6a726e118fc7c0e799cea01bb707436:0        # 从 master server 进行全量同步
1578:S 24 Jun 13:31:49.992 * Discarding previously cached master state.
1578:S 24 Jun 13:31:50.089 * MASTER <-> SLAVE sync: receiving 240 bytes from master # 接收到 master server 发来的数据
1578:S 24 Jun 13:31:50.095 * MASTER <-> SLAVE sync: Flushing old data       ## 清除旧数据
1578:S 24 Jun 13:31:50.098 * MASTER <-> SLAVE sync: Loading DB in memory    ## 将 master server 发来的数据加载到内存
1578:S 24 Jun 13:31:50.106 * MASTER <-> SLAVE sync: Finished with success   ## 完成同步
1578:S 24 Jun 13:31:50.572 - DB 0: 3 keys (0 volatile) in 4 slots HT.
......
Redis 增量复制过程的验证

关闭 slave server 的网络,在 master server 增加一条数据,然后重新打开 slave server 的网络。日志如下:

1676:S 24 Jun 14:05:27.579 - DB 0: 4 keys (0 volatile) in 4 slots HT.
1676:S 24 Jun 14:05:27.579 - 3 clients connected (0 slaves), 1897296 bytes in use
1676:S 24 Jun 14:05:30.657 # MASTER timeout: no data nor PING received...   # 与 master server 连接超时
1676:S 24 Jun 14:05:30.657 # Connection with master lost.
1676:S 24 Jun 14:05:30.657 * Caching the disconnected master state.
1676:S 24 Jun 14:05:30.658 * Connecting to MASTER 192.168.1.128:6379    # 重新连接到 master server 
1676:S 24 Jun 14:05:30.670 * MASTER <-> SLAVE sync started  # 开始同步数据
1676:S 24 Jun 14:05:32.704 - DB 0: 4 keys (0 volatile) in 4 slots HT.
1676:S 24 Jun 14:05:32.704 - 2 clients connected (0 slaves), 1897272 bytes in use
1676:S 24 Jun 14:05:32.713 * Non blocking connect for SYNC fired the event. # 发送 SYNC 命令
1676:S 24 Jun 14:05:32.727 * Master replied to PING, replication can continue...
1676:S 24 Jun 14:05:32.734 * Trying a partial resynchronization (request 18aca6a0c6a726e118fc7c0e799cea01bb707436:2402).        # 进行增量同步
1676:S 24 Jun 14:05:32.741 * Successful partial resynchronization with master.  # 同步完成
1676:S 24 Jun 14:05:32.741 * MASTER <-> SLAVE sync: Master accepted a Partial Resynchronization.
1676:S 24 Jun 14:05:37.841 - DB 0: 5 keys (0 volatile) in 8 slots HT.
1676:S 24 Jun 14:05:37.841 - 3 clients connected (0 slaves), 1897392 bytes in use
1676:S 24 Jun 14:05:42.957 - DB 0: 5 keys (0 volatile) in 8 slots HT.

主从模式的优缺点


Redis的Replication的特点和优点:
  • 同一个Master可以同步多个Slaves。
  • Slave同样可以接受其它Slaves的连接和同步请求,这样可以有效的分载Master的同步压力。因此我们可以将Redis的Replication架构视为图结构。
  • Master Server是以非阻塞的方式为Slaves提供服务。所以在Master-Slave同步期间,客户端仍然可以提交查询或修改请求。
  • Slave Server同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据。
  • 为了分载Master的读操作压力,Slave服务器可以为客户端提供只读操作的服务,写服务仍然必须由Master来完成。即便如此,系统的伸缩性还是得到了很大的提高。
  • Master可以将数据保存操作交给Slaves完成,从而避免了在Master中要有独立的进程来完成此操作。
  • 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。
Redis的Replication的缺点:
  • Redis不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。
  • 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
  • Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。
总结

Redis 的主从模式很简单,但在实际的生产环境中却是很少使用的,我也不建议在实际的生产环境中使用主从模式来提供系统的高可用性,之所以不建议使用都是由它的缺点造成的,在数据量非常大的情况,或者对系统的高可用性要求很高的情况下,主从模式也是不稳定的。虽然这个模式很简单,但是这个模式是其他模式的基础,所以必须深刻的理解,对其他模式的学习才会有帮助作用。



参考文章:

猜你喜欢

转载自blog.csdn.net/liupeifeng3514/article/details/80791017