浅析Redis复制过程

摘要

Redis默认使用异步复制,其特点是低延迟和高性能。异步复制就意味着在故障转移期间,有丢失数据的风险。你可以参考Redis 集群文档,了解关于高可用性和故障转移的信息,本文主要讨论Redis 复制功能的基本特性。

复制

在 Redis 复制的基础上,使用和配置主从复制非常简单,能使得从 Redis 服务器(Slave)能精确得复制主 Redis 服务器(Master)的内容。每次当 Slave 和 Master 之间的连接断开时, Slave 会自动重连到 Master 上,并且无论这期间 Master 发生了什么, Slave 都将尝试让自身成为 Master 的精确副本。

复制的运行依靠三个主要的机制:

  • 当一个 Master 实例和一个 Slave 实例连接正常时, Master 将自身数据集的改变以命令流的方式保持对 Slave 的更新,包括客户端的写入、key 的过期或被逐出等等。
  • 当 Master 和 Slave 之间的连接断开之后,因为网络问题、或者是主从连接超时, Slave 重新连接上 Master 并会尝试进行部分重同步:这意味着它会尝试只获取在断开连接期间内丢失的命令流。
  • 当无法进行部分重同步时, Slave 会请求进行全量重同步。这会涉及到一个更复杂的过程,Master 需要创建所有数据的快照,将之发送给 Slave ,之后在数据集更改时持续发送命令流到 Slave 。

以下是一些关于复制的重要事项:

  • 异步复制

  • 一个Master可以对应多个Slave

  • Slave 可以接受其他 Slave 的连接

  • 复制在 Master 侧是非阻塞的

  • 复制在 Slave 侧大部分时间也是非阻塞的

    在初次同步之后,旧数据集必须被删除,同时加载新的数据集。 Slave 在这个短暂的时间窗口内会阻塞到来的连接请求。

  • 可以使用复制来避免 Master 将全部数据集写入磁盘造成的开销

    一种典型的例子是Master 关闭持久化,然后连接一个 Slave ,其配置为RDB或者 AOF。但是,这个设置必须小心处理,因为重新启动的 Master 程序将从一个空数据集开始:如果一个 Slave 试图与它同步,那么这个 Slave 也会被清空。

当 Master 关闭持久化时,复制的安全性

在使用 Redis 复制功能的设置中,强烈建议在 Master 和 Slave 中启用持久化。当不可能启用时,例如由于磁盘性能而导致的延迟问题,应该通过设置避免maste故障后自动重启

通过下面例子,可以更好地理解关闭了持久化并配置了自动重启的 Master 是危险的:

  1. 设置节点 A 为 Master 并关闭它的持久化设置,节点 B 和 C 从 节点 A 复制数据。
  2. 节点 A 崩溃,但是可能有自动重启的运维系统可以重启进程。但是由于持久化被关闭了,节点重启后其数据集合为空。
  3. 节点 B 和 节点 C 会从节点 A 复制数据,但是节点 A 的数据集是空的,因此复制的结果是BC会销毁自身之前的数据副本。

在这里插入图片描述

任何时候数据安全性都是很重要的,如果 Master 使用复制功能的同时未配置持久化,那么自动重启进程这项应该被禁用。

复制的工作原理

每一个 Redis Master 都有一个 replication ID :这是一个较大的伪随机字符串,标记了一个给定的数据集。每个 Master 持有一个偏移量,Master 将自己产生的复制流发送给 Slave 时,发送多少个字节的数据,自身的偏移量就会增加多少,目的是当有新的操作修改自己的数据集时,它可以以此更新 Slave 的状态。复制偏移量即使在没有一个 Slave 连接到 Master 时,也会自增,所以基本上每一对给定的(Replication ID, offset)都会标识一个 Master 数据集的确切版本。

当 Slave 连接到 Master 时,它们使用 PSYNC 命令来发送它们记录的旧的 Master replication ID 和它们至今为止处理的偏移量。通过这种方式, Master 能够仅发送 Slave 所需的增量部分。但是如果 Master 的缓冲区中没有足够的命令积压缓冲记录,或者如果 Slave 引用了不再知道的历史记录(replication ID),则会转而进行一个全量重同步:在这种情况下, Slave 会得到一个完整的数据集副本,从头开始。

全量重同步的详细过程:

Master 开启一个后台保存进程,以便于生产一个 RDB 文件。同时它开始缓冲所有从客户端接收到的新的写入命令。当后台保存完成时, Master 将数据集文件传输给 Slave, Slave将之保存在磁盘上,然后加载文件到内存。再然后 Master 会发送所有缓冲的命令发给 Slave。这个过程以指令流的形式完成。

下图是一个简单的同步例子:

在这里插入图片描述
针对上图情况的进一步说明:

  • Master A在长期的运行过程中,可能会遇到重启或者是由故障转移提升为Master的,所以它的缓存区可能存在多对(Replication ID, offset)。
  • 当Slave B首次连接到Master A时,发送PSYNC(290069241989391187,0)给Master A,Master A收到请求后找到replication ID:290069241989391187的数据集,把offset:0~22处的数据集发送给Slave B,Master A的偏移量自增22,Slave B收到Master A返回的命令流后,逐一执行,并修改offset为22。
  • Slave C发送PSYNC(2900692419893910001,33)给Master A,Master A发现replication ID:2900692419893910001不存在缓冲区中,则向Slave C发送全量数据(RDB文件),这样Slave C就能得到一个完整的数据,对于Master A以后的同步,采用和Slave B中描述的同步方式。

配置

配置基本的 Redis 复制功能很简单:只需要将以下内容加进 Slave 的配置文件:

# slaveof <masterip> <masterport>
slaveof 192.168.33.160 6379

# masterauth <master-password>
masterauth 123456

当然你也可以使用 SLAVEOF 命令,

只读 Slave

redis.conf 文件中的 slave-read-only 变量控制只读,自从Redis 2.6以后,该值默认yes,且可以在运行时使用 CONFIG SET slave-read-only来随时开启或者关闭。只读模式下的 Slave 将会拒绝所有写入命令。redis.conf 文件中使用 rename-command 指令可以禁用 CONFIG等管理员命令以提高只读实例的安全性。

需要注意的是,从Redis 4.0开始,Slave的数据传播将从最顶层Master向低层所有Slave发送相同的命令流。例如,A -> B -> C,B和C的复制都是从A中获取命令流。

写入Master

只有当至少有 N 个 Slave滞后小于 M 秒,Redis Master 的写入操作才会成功,否则,返回 error。

N:slave 数量;

M:秒数;

Master可以配置这两个配置参数:

  • min-slaves-to-write <slave 数量>
  • min-slaves-max-lag <秒数>

以下是该特性的工作原理:

  • Redis Slave 每秒钟都会 ping Master,确认已处理的复制流的数量。
  • Redis Master 会记得上一次从每个 Slave 都收到 ping 的时间。
  • Master通过判断是否至少有 N 个 Slave滞后小于 M 秒,来确定写入还是返回error。

这是一个尽最大努力保证数据安全的机制,对于写入来说,不能保证一致性,但至少数据丢失的时间窗限制在指定的秒数内。

Slave如何处理key的过期

为了实现Slaves能正确地复制具有过期时间的 key,Redis 使用三种主要的技术:

  • Slave 不会让 key 过期,而是等待 Master 让 key 过期。当一个 Master 让一个 key 到期(或由于 LRU 算法将之驱逐)时,它会合成一个 DEL 命令并传输到所有的 Slave。
  • 但是,由于这是 Master 驱动的 key 过期行为,Master 无法及时提供 DEL 命令,所以有时候 Slave 的内存中仍然可能存在在逻辑上已经过期的 key 。为了处理这个问题,Slave 使用它的逻辑时钟,只用于不违反数据集一致性的读取操作。(也就是说Master的命令流能够识别改key存在,其他的任何读取操作无法读到该key。)
  • 在Lua脚本执行期间,不执行任何 key 过期操作。当一个Lua脚本运行时,从理论上讲,Master 中的时间是被冻结的,这样脚本运行的时候,一个给定的键要么存在要么不存在。

需要注意的是,一旦Slave 被提升为一个 Master,它将独立地依靠本地时钟处理key的过期,而不需要任依赖Master。

参考

[1] Replication.

发布了20 篇原创文章 · 获赞 77 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_36011946/article/details/105456532
今日推荐