redis 系列21 复制Replication (上)

 一.   概述

  使用和配置主从复制非常简单,每次当 slave 和 master 之间的连接断开时, slave 会自动重连到 master 上,并且无论这期间 master 发生了什么, slave 都将尝试让自身成为 master 的精确副本。这个系统的运行依靠三个主要的机制:

  (1) 当一个 master 实例和一个 slave 实例连接正常时, master 会发送一连串的命令流来保持对 slave 的更新,以便于将自身(master)数据集的改变复制给 slave 。包括客户端的写入、key 的过期或master库的其它改变动作。

  (2) 在Redis2.6之前,主从断开重连后,会进行一次快照操作(rdb)然后将快照发送给从数据库,即使断开期间只有几条命令被执行,这就使得断开重联后的数据恢复过程效率很低。Redis2.8之后,当 master 和 slave 之间的连接断开之后(因为网络问题、主库或从库检测到超时), slave 会重新连接上 master 并尝试进行"部分重同步"也叫增量复制(partial resynchronization),用于获取在断开连接期间内丢失的命令流。

  (3) 当无法进行部分重同步时,slave 会请求进行"完整同步"(full resynchronization)。这会涉及到一个更复杂的过程,例如 master 需要创建所有数据的快照,将之发送给 slave ,之后在master数据集更改时持续发送命令流到 slave。也就是2.8后有了全部同步和部分重同步两种模式,而2.6之前只有全部同步模式。

  

二. 复制特点

  Redis使用默认的异步复制,具有低延迟和高性能,是绝大多数Redis使用的复制模式。从库会异步的确认与主库定期接收到的数据量。主库不会每次去等待从库处理完命令。类似mysql半同步复制功能可以通过min-slaves配置选项来辅助。下面介绍Redis复制的一些特点:

  (1) Redis使用异步复制,slave 和 master 之间异步地确认处理的数据量。

  (2) 一个 master 可以拥有多个 slave。

  (3) slave 可以接受其他 slave 的连接。除了多个 slave 可以连接到同一个 master 之外, slave 之间也可以像层叠状的结构(cascading-like structure)连接到其他 slave 。自Redis 4.0 版本起所有的 sub-slave 将会从 master 收到完全一样的复制流。

  (4) Redis复制在 master这边是非阻塞的。这意味着 master 在一个或多个 slave 进行初次同步或者是部分重同步时,可以继续处理查询请求。

  (5) 复制在 slave 这边大部分也是非阻塞的。当 slave 进行初次同步时,它可以使用旧数据集处理查询请求,假设你在redis.conf中配置了让Redis这样做的话。

  (6) 复制既可以被用在可伸缩性,以便只读查询可以有多个 slave 进行(例如 O(N) 复杂度的慢操作可以被下放到 slave ),或者仅用于数据安全。

  (7) 可以使用复制来避免 master 将全部数据集写入磁盘造成的开销:一种典型的技术是配置你的 master Redis.conf以避免对磁盘进行持久化,然后连接一个 slave ,其配置为不定期保存或是启用 AOF。但是,这个设置必须小心处理,因为重新启动的 master 程序将从一个空数据集开始:如果一个 slave 试图与它同步,那么这个 slave 也会被清空。

  (8) 在使用Redis复制功能时,强烈建议在 master 和在 slave 中启用持久化。假如:持久化被关闭了,Redis主节点重启后其数据集合为空。而其它slave从节点会复制主节点数据,在复制时会销毁自身之前的数据副本。这样下来复制构架的所有节点数据都会被清空。

 

三 Redis复制同步原理

  3.1 全部同步的实现

    当客户端向从服务器发送slaveof命令,要求从服务器复制主服务器时,从服务器首先需要执行同步操作,将从服务器的数据库状态更新至主服务器当前所处的数据库状,过程如下:

      (1) 从服务器向主服务器发送psync命令。

      (2) 收到psync命令的主服务器执行BGSAVE命令,开启一个后台子进程生成一个 RDB 快照文件,并同时使用一个缓冲区记录从现在执行的所有写命令。

      (3) 当主服务器的BGSAVE命令执行完,主服务器会将生成的RDB文件发送给从服务器,从服务器接收并载入这个RDB文件,然后加载文件到内存。将自己的数据库状态更新至主服务器执行BGSAVE命令时的数据库状态。

      (4) 主服务器将记录在缓冲区里面的所有写命令发送给从服务器,从服务器执行这些写命令,将自己的数据库状态更新至主服务器数据库当前所处状态。这个过程以指令流的形式完成并且和Redis协议本身的格式相同。

      下面是使用psync命令进行全部同步的过程:

时间

主服务器

从服务器

T0

服务器启动

服务器启动

T1

执行set  k1  v1

 

T2

执行set  k2  v2

 

T4

..

向主服务器发送psync命令

T5

接收到从服务器的psync命令,执行bgsave命令,创建RDB文件,并使用缓冲区记录接下来执行所有写命令.

 

T6

执行set  k3  v3,将这个命令记录在缓冲区中

 

T7

执行set  k4  v4,将这个命令记录在缓冲区中

 

T8

Bgsave执行完成,向从服务器发送RDB文件

 

T9

 

接收载入RDB文件

T10

向从服务器发送缓冲区中保存的写命令

 

T11

 

接收缓冲区中的写命令,执行

T12

同步完成

同步完成

  

关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信