5. Redis 复制 (Replication)


文档摘要

Redis 复制 (Replication) Redis 复制 (Replication) 详解与实践 Redis 复制 (Replication) 是 Redis 高可用性和数据冗余的关键特性。它允许将 Redis 数据从一个服务器(主节点,Master)复制到一个或多个其他服务器(从节点,Slave 或 Replica)。当主节点数据发生变化时,会自动将数据同步到所有从节点,从而实现数据备份和读写分离。 本文将深入探讨 Redis 复制的原理、配置、工作流程、实践应用以及一些高级特性,帮助您全面理解和掌握 Redis 复制技术。 Redis 复制的核心概念与优势 在深入代码实践之前,我们先来了解 Redis 复制的核心概念和优势: 1.

5. Redis 复制 (Replication)

Redis 复制 (Replication) 详解与实践

Redis 复制 (Replication) 是 Redis 高可用性和数据冗余的关键特性。它允许将 Redis 数据从一个服务器(主节点,Master)复制到一个或多个其他服务器(从节点,Slave 或 Replica)。当主节点数据发生变化时,会自动将数据同步到所有从节点,从而实现数据备份和读写分离。

本文将深入探讨 Redis 复制的原理、配置、工作流程、实践应用以及一些高级特性,帮助您全面理解和掌握 Redis 复制技术。

1. Redis 复制的核心概念与优势

在深入代码实践之前,我们先来了解 Redis 复制的核心概念和优势:

1.1 核心概念

  • 主节点 (Master): 负责处理所有写操作和部分读操作(默认情况下,读操作也可以分发到从节点,但通常主节点承担写操作)。主节点的数据是数据源。

  • 从节点 (Slave/Replica): 从主节点复制数据,主要用于处理读操作,分担主节点的读压力,并作为数据备份。从节点接收主节点的更新并应用这些更新,保持与主节点数据同步。

  • 全量复制 (Full Synchronization): 当从节点首次连接主节点或复制过程中断后,主节点会将完整的数据集(RDB 文件)发送给从节点进行同步。

  • 增量复制 (Partial Synchronization): 在网络中断后恢复连接时,如果条件允许(复制偏移量在 backlog 中),主节点只会发送断开期间产生的增量数据,提高同步效率。

  • 复制偏移量 (Replication Offset): 主节点和从节点都会维护一个复制偏移量,用于跟踪数据同步的进度。主节点记录已发送给从节点的字节数,从节点记录已接收并应用的字节数。

  • 复制积压缓冲区 (Replication Backlog): 主节点维护一个环形缓冲区,用于存储最近一段时间的写命令。当从节点断线重连后,如果请求的偏移量还在 backlog 中,主节点可以进行增量复制。

  • Run ID (运行 ID): 每个 Redis 服务器实例在启动时都会生成一个唯一的 Run ID。Run ID 用于标识服务器实例,当主从切换时,从节点需要识别新的主节点。

1.2 复制的优势

  • 数据冗余与备份: 从节点作为主节点数据的副本,在主节点发生故障时,可以提供数据备份,提高数据安全性。

  • 读写分离与负载均衡: 读操作可以分发到多个从节点执行,减轻主节点的读压力,提高整体系统的吞吐量。

  • 提高可用性: 当主节点发生故障时,可以手动或自动将从节点提升为主节点,实现故障转移,提高系统的可用性。(配合 Sentinel 或 Cluster 更能实现自动故障转移)

  • 支持在线扩容: 可以通过增加从节点来扩展系统的读能力,实现水平扩展。

2. Redis 复制的配置与实践

接下来,我们将通过代码实践来演示如何配置和使用 Redis 复制。

2.1 环境准备

为了演示 Redis 复制,我们需要准备至少两台 Redis 服务器:一台作为主节点,一台作为从节点。您可以在同一台机器上启动多个 Redis 实例,通过不同的端口来模拟主从环境。

假设我们有以下配置:

  • 主节点 (Master):

    • IP: 127.0.0.1 (或您的主节点 IP)

    • 端口: 6379 (默认端口)

  • 从节点 (Slave):

    • IP: 127.0.0.1 (或您的从节点 IP)

    • 端口: 6380 (或您选择的端口)

2.2 配置从节点连接主节点

配置从节点连接主节点主要有两种方式:

方法一:通过 redis.conf 配置文件

  1. 编辑从节点的 redis.conf 文件 (例如 redis-slave.conf)。 如果您是复制默认的 redis.conf,请确保修改端口号,例如:

    port 6380 pidfile /var/run/redis_6380.pid logfile "redis-slave.log" dir /usr/local/redis/data/slave
  2. redis-slave.conf 文件中添加 replicaof 配置指令。 将以下配置添加到 redis-slave.conf 文件中,指定主节点的 IP 和端口:

    replicaof 127.0.0.1 6379
    • replicaof <masterip> <masterport>: 指定当前 Redis 实例作为从节点,并连接到指定 IP 和端口的主节点。

    • 在 Redis 5.0 之前的版本,使用的是 slaveof <masterip> <masterport> 指令,功能相同。为了兼容性和语义更清晰,建议使用 replicaof

  3. (可选)配置主节点认证密码 (如果主节点启用了 requirepass)。 如果主节点配置了密码认证,需要在从节点的 redis.conf 中添加 masterauth 配置:

    masterauth your_master_password
    • masterauth <master-password>: 指定连接主节点时使用的密码。
  4. 启动从节点实例。 使用修改后的配置文件启动从节点:

    redis-server redis-slave.conf

方法二:通过 redis-cli 客户端命令

  1. 启动从节点实例 (可以使用默认配置启动,或者指定配置文件)。

  2. 使用 redis-cli 连接到从节点。

    redis-cli -p 6380
  3. redis-cli 客户端中执行 replicaof 命令。

    127.0.0.1:6380> replicaof 127.0.0.1 6379 OK
    • 同样,如果主节点有密码,需要先使用 AUTH 命令进行认证,或者在 replicaof 命令前使用 AUTH 命令。
    127.0.0.1:6380> AUTH your_master_password OK 127.0.0.1:6380> replicaof 127.0.0.1 6379 OK

2.3 验证复制状态

配置完成后,我们需要验证复制是否成功建立。

  1. 连接到主节点 (端口 6379) 并执行 INFO replication 命令。

    redis-cli -p 6379 127.0.0.1:6379> INFO replication # Replication role:master connected_slaves:1 slave0:ip=127.0.0.1,port=6380,state=online,offset=XXXX,lag=0 master_replid:XXXXXXXXXXXX master_replid2:0000000000000000000000000000000000000000 master_repl_offset:XXXX second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:XXXX
    • role:master: 表示当前实例为主节点。

    • connected_slaves:1: 表示当前主节点连接了一个从节点。

    • slave0:ip=127.0.0.1,port=6380,state=online,offset=XXXX,lag=0: 显示连接的从节点信息,state=online 表示从节点在线,lag=0 表示复制延迟为 0 秒 (理想状态)。 offset 表示复制偏移量。

  2. 连接到从节点 (端口 6380) 并执行 INFO replication 命令。

    redis-cli -p 6380 127.0.0.1:6380> INFO replication # Replication role:slave master_host:127.0.0.1 master_port:6379 master_link_status:up master_last_io_seconds_ago:0 master_sync_in_progress:0 slave_repl_offset:XXXX slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:XXXXXXXXXXXX master_replid2:0000000000000000000000000000000000000000 master_repl_offset:XXXX second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:XXXX
    • role:slave: 表示当前实例为从节点。

    • master_host:127.0.0.1: 显示主节点的 IP 地址。

    • master_port:6379: 显示主节点的端口号。

    • master_link_status:up: 表示与主节点的连接状态正常。

    • slave_read_only:1: 默认情况下,从节点是只读的,不允许写操作。

  3. 测试数据同步。

    • 在主节点 (端口 6379) 设置一个键值对:

      127.0.0.1:6379> SET mykey "hello from master" OK
    • 在从节点 (端口 6380) 获取该键值对:

      127.0.0.1:6380> GET mykey "hello from master"

    如果从节点能够成功获取到主节点设置的键值对,则说明复制配置成功,数据同步正常工作。

2.4 从节点的只读属性

默认情况下,Redis 从节点是只读的,不允许客户端执行写操作。这是为了保证数据一致性和避免数据冲突。

  • 尝试在从节点执行写操作:

    127.0.0.1:6380> SET anotherkey "write to slave" (error) READONLY You can't write against a read only replica.

    从错误信息 READONLY You can't write against a read only replica. 可以看到,从节点拒绝了写操作。

  • 修改从节点的只读属性 (不推荐): 可以通过修改从节点的 redis.conf 文件或使用 CONFIG SET slave-read-only no 命令来关闭从节点的只读属性。 强烈不建议这样做,因为这会引入数据一致性风险,并可能导致数据混乱。 除非您非常清楚自己在做什么,并且有充分的理由需要从节点可写。

2.5 断开与主节点的复制连接

可以使用 replicaof no one (或旧版本 slaveof no one) 命令来断开从节点与主节点的复制连接。

127.0.0.1:6380> replicaof no one OK

断开连接后,从节点将停止从主节点同步数据,并变成一个独立的 Redis 实例。之前从主节点同步的数据仍然保留在从节点中。

3. Redis 复制的工作流程详解

Redis 复制的工作流程可以分为几个关键阶段:

3.1 连接建立阶段

  1. 从节点启动并配置 replicaof 指令。 从节点启动后,会读取配置文件或接收 replicaof 命令,获取主节点的 IP 和端口信息。

  2. 从节点尝试连接主节点。 从节点会根据配置信息,尝试与主节点建立网络连接。

  3. 认证 (可选)。 如果主节点配置了 requirepass,从节点需要使用 masterauth 配置的密码进行认证。

  4. 发送 PING 命令。 从节点向主节点发送 PING 命令,检查主节点是否正常运行。

  5. 发送 REPLCONF listening-port 命令。 从节点将自己的监听端口发送给主节点。

3.2 全量复制 (Full Synchronization) 阶段

这是首次连接或断线后重连且无法进行增量复制时发生的阶段。

  1. 主节点开始生成 RDB 文件。 主节点在后台启动一个子进程,将内存中的数据快照生成 RDB 文件。同时,主节点会继续接收客户端的写命令,并将这些写命令缓存在复制缓冲区中。

  2. 主节点将 RDB 文件发送给从节点。 主节点将生成的 RDB 文件通过网络发送给从节点。

  3. 从节点清空旧数据并加载 RDB 文件。 从节点接收到 RDB 文件后,会先清空自身所有旧数据,然后加载 RDB 文件,将数据恢复到与主节点一致的状态。

  4. 主节点发送复制缓冲区中的命令。 RDB 文件发送完成后,主节点会将复制缓冲区中缓存的在生成 RDB 文件期间收到的写命令发送给从节点。

  5. 从节点执行接收到的命令。 从节点执行接收到的写命令,应用到自己的数据集上,完成全量数据同步。

3.3 增量复制 (Partial Synchronization) 阶段

在全量复制完成后,主从节点进入增量复制阶段,也称为命令传播阶段。

  1. 主节点持续将写命令发送给从节点。 当主节点接收到新的写命令时,除了执行命令更新自身数据外,还会将这些写命令发送给所有已连接的从节点。

  2. 从节点接收并执行写命令。 从节点接收到主节点发送的写命令后,会解析并执行这些命令,更新自己的数据集,保持与主节点数据同步。

  3. 心跳检测。 从节点会定期向主节点发送心跳包 (默认每秒一次),用于检测主从连接状态,并汇报自己的复制偏移量。主节点也会定期检查从节点的心跳,判断从节点是否正常工作。

3.4 PSYNC 优化

Redis 2.8 版本引入了 PSYNC 命令,用于优化复制同步过程,特别是针对断线重连的情况。PSYNC 可以实现更高效的增量复制,减少全量复制的频率。

  • Run ID 和 Offset: PSYNC 的核心机制是利用 Run ID 和复制偏移量。每个 Redis 实例都有一个唯一的 Run ID,用于标识实例。主从节点都维护复制偏移量,跟踪数据同步进度。

  • 复制积压缓冲区 (Replication Backlog): 主节点维护一个环形缓冲区,存储最近一段时间的写命令。

  • 增量复制流程: 当从节点断线重连后,会向主节点发送 PSYNC 命令,并携带自己的 Run ID 和复制偏移量。

    • 如果 Run ID 匹配且偏移量在 backlog 范围内: 主节点会判断从节点的 Run ID 是否与自己的 Run ID 一致,以及从节点请求的偏移量是否还在复制积压缓冲区中。如果都满足条件,主节点只会发送从节点断线期间错过的增量数据,进行增量复制。

    • 如果 Run ID 不匹配或偏移量超出 backlog 范围: 如果 Run ID 不匹配(例如主节点重启过)或者从节点请求的偏移量已经超出复制积压缓冲区的范围,主节点无法进行增量复制,会执行全量复制。

4. 复制相关的配置选项详解

除了 replicaofmasterauth,Redis 复制还提供了一些其他重要的配置选项,可以在 redis.conf 文件中进行配置。

  • repl-diskless-sync yes|no (默认 no)

    • 是否启用无磁盘复制。

    • no: (默认) 主节点在全量复制时,先将 RDB 文件写入磁盘,然后再从磁盘发送给从节点。

    • yes: 主节点在全量复制时,直接在内存中生成 RDB 文件,并通过网络管道直接发送给从节点,不写入磁盘。

    • 优点 (无磁盘复制): 减少磁盘 I/O,加快全量复制速度,尤其是在磁盘 I/O 成为瓶颈时。

    • 缺点 (无磁盘复制): 如果多个从节点同时请求全量复制,主节点需要多次生成 RDB 数据并通过网络发送,会消耗更多 CPU 和网络带宽。如果复制过程中网络中断,需要重新全量复制。

    • 适用场景: 高速网络环境,磁盘 I/O 瓶颈,对复制速度要求高。

  • repl-diskless-sync-delay <seconds> (默认 5)

    • 无磁盘复制的延迟时间。

    • 当启用无磁盘复制时,主节点不会立即开始发送 RDB 数据,而是等待一段时间(默认 5 秒),等待更多从节点连接并开始复制。这样可以将多个从节点的复制请求合并到一个 RDB 数据流中,减少 RDB 生成次数,节省资源。

    • 0: 禁用延迟,立即开始发送。

  • repl-backlog-size <bytes> (默认 1mb)

    • 复制积压缓冲区的大小。

    • 用于存储最近一段时间的写命令,支持增量复制。

    • 如果从节点断线时间过长,导致需要的偏移量超出 backlog 范围,则无法进行增量复制,需要全量复制。

    • 可以根据实际情况调整 backlog 大小,通常设置为能容纳主从网络延迟期间产生的写命令即可。

  • repl-backlog-ttl <seconds> (默认 3600)

    • 复制积压缓冲区的最大存活时间。

    • 如果 backlog 中的数据超过 repl-backlog-ttl 秒没有被任何从节点使用,则会被释放。

  • replica-priority <integer> (默认 100)

    • 从节点的优先级。

    • 在主节点故障时,Sentinel 或 Cluster 会根据从节点的优先级选择提升哪个从节点为主节点。优先级数值越小,优先级越高。

    • 如果设置为 0,则该从节点永远不会被选为主节点。

  • replica-read-only yes|no (默认 yes)

    • 从节点是否只读。

    • yes: (默认) 从节点只读,不允许写操作。

    • no: 从节点可读写 (不推荐)。

  • repl-timeout <seconds> (默认 60)

    • 复制相关的超时时间,包括:

      • 主节点等待从节点发送 REPLCONF ACK 的超时时间。

      • 全量复制期间,主节点发送 RDB 数据的超时时间。

      • 从节点等待主节点发送数据的超时时间。

  • tcp-keepalive <seconds> (默认 300)

    • TCP Keepalive 检测间隔时间。

    • 用于检测主从节点之间的 TCP 连接是否存活。

5. 复制的监控与管理

5.1 使用 INFO replication 命令监控复制状态

如前文所述,可以使用 INFO replication 命令查看主节点和从节点的复制状态,包括角色、连接的从节点信息、复制偏移量、延迟等。这是最常用的监控复制状态的方式。

5.2 使用 Redis Sentinel 进行监控和自动故障转移

在生产环境中,为了实现更高的可用性,通常会配合 Redis Sentinel 使用复制。Redis Sentinel 提供了以下功能:

  • 监控 (Monitoring): Sentinel 会定期检查主节点和从节点的健康状态。

  • 通知 (Notification): 当被监控的 Redis 实例状态发生变化时,Sentinel 会向客户端发送通知。

  • 自动故障转移 (Automatic Failover): 当 Sentinel 检测到主节点故障时,会自动将一个从节点提升为主节点,并通知其他从节点和客户端更新主节点信息。

5.3 使用 Redis Cluster 实现更高级的复制和分片

Redis Cluster 是 Redis 的分布式解决方案,它内置了复制和分片功能。Cluster 将数据分散存储在多个节点上,每个节点可以有多个从节点进行复制。Cluster 提供了更强大的高可用性和扩展性。

6. 总结与最佳实践

Redis 复制是构建高可用、高性能 Redis 服务的基石。合理配置和使用复制可以带来以下好处:

  • 数据安全: 通过数据冗余提高数据安全性,防止数据丢失。

  • 性能提升: 通过读写分离分担主节点读压力,提高系统吞吐量。

  • 高可用性: 配合 Sentinel 或 Cluster 实现自动故障转移,提高系统可用性。

最佳实践建议:

  • 至少配置一个从节点: 生产环境建议至少配置一个从节点,提供数据备份和读扩展能力。

  • 使用密码认证: 为主节点配置密码认证,并配置从节点的 masterauth,提高安全性。

  • 合理配置 repl-backlog-size: 根据网络延迟和业务特点,合理配置复制积压缓冲区大小,避免频繁全量复制。

  • 监控复制状态: 定期使用 INFO replication 命令监控复制状态,确保复制正常工作。

  • 配合 Sentinel 或 Cluster: 在生产环境中使用 Redis Sentinel 或 Cluster 实现自动故障转移和更高级的复制管理。

  • 注意网络延迟: 主从节点之间的网络延迟会影响复制性能和数据一致性,尽量将主从节点部署在网络良好的环境中。

  • 谨慎开启从节点可写: 除非有特殊需求,否则不要开启从节点的写操作,避免数据一致性问题。

希望本文能够帮助您深入理解 Redis 复制的原理和实践,并在实际应用中正确配置和使用 Redis 复制,构建稳定可靠的 Redis 服务。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U