Redis主从复制

Redis 主从复制:原理与实战

一、理论

整体机制

  • 主从复制是异步 的、单向的:数据从主节点流向从节点,写操作只能在主节点上做,从节点默认只读。
  • "异步"的意思是主节点把写命令发给从节点后并不等待确认,就直接回复客户端。好处是不影响主节点的性能,代价是主节点突然宕机时,最后一批还没传过去的写入会丢失。
  • 主从复制本身不包含自动故障切换。它只解决数据冗余和读扩展,要做到主节点挂了自动顶上,还需要 Sentinel(哨兵)或 Redis Cluster。

一次完整的主从关系建立,会经历三件事:

  1. 建立连接、协商同步方式
  2. 全量同步(第一次连接时,或无法做增量同步时)
  3. 命令传播(之后持续进行的增量同步)

在学习 Redis 主从复制前,我们需要知道三个关键概念:

概念 含义
run_id(复制 ID) 每个 Redis 实例启动时生成的 40 位随机字符串,标识它这一次"生命期"。从节点重连时用它判断主节点是不是换过一个了
复制偏移量 offset 主节点每发出 N 字节写命令就累加自己的 offset,从节点每收到也累加。双方 offset 一致,说明数据一致
复制积压缓冲区 backlog 主节点维护的一个固定大小的环形缓冲区(由 repl-backlog-size 控制,默认 1MB),保存最近发出去的写命令,用来支持断线后只补差量

不同于 MySQL 的 mysqldump 全量备份与二进制日志持续同步,Redis 有其独特的机制。下面简单介绍一下 Redis 主从复制机制,有助于我们知道后续配置文件都在配置什么。

全量同步:原理是 RDB 快照

从节点在配置里写上 replicaof(旧版本叫 slaveof)之后:

  1. 从节点主动连接主节点,先发一个 PING 确认对方可用
  2. 如果主节点设了密码,从节点用配置里的 masterauth 完成认证
  3. 从节点发送 REPLCONF listening-port <端口>,告诉主节点自己的端口
  4. 从节点发送 PSYNC ? -1,表示"我是第一次来,做全量同步"
  5. 主节点回复 FULLRESYNC <run_id> <offset>,同时 fork 出一个子进程生成 RDB 快照
  6. 生成快照的这段时间里,主节点新收到的写命令会暂存到复制缓冲区里
  7. 主节点把 RDB 文件发送给从节点(配置 repl-diskless-sync yes 时可以走无盘复制,直接把数据写进 socket,省掉落盘再读取的开销)
  8. 从节点收到 RDB 后,先清空自己原有的数据,再加载这份快照
  9. 加载完成后,主节点把缓冲区里积攒的增量命令补发过去,双方 offset 对齐,数据就一致了

增量同步:围绕三个核心概念

增量备份主要围绕三个核心概念:run_id、offset 和 backlog 缓冲区。

链路断开后重连时,从节点会带上自己记录的 run_id 和 offset 再发一次 PSYNC:

  • 如果主节点的 run_id 没变,并且 offset 之后的数据还都在 backlog 里,主节点就回复 +CONTINUE,只把缺失的那一小段命令补发给从节点,代价很低
  • 如果主节点重启过(run_id 变了),或者断开时间太久、缺的数据已经超出 backlog 的范围,就只能重新做一次全量复制

所以把 repl-backlog-size 调大,能提高"断线重连只需增量同步"的概率。

心跳与超时:Redis 怎么确认连接断了

  • 主节点默认每 10 秒向从节点发一次 PING,由 repl-ping-replica-period 控制
  • 从节点默认每秒向主节点回一个 REPLCONF ACK <offset>,汇报自己收到哪了
  • 如果超过 repl-timeout(默认 60 秒)双方都没收到对方的消息,就判定连接断开
  • 用 INFO replication 看到的 master_link_status:up,就是指这条链路是通的

几个实用结论

  • 首次建立主从、或者断线太久导致 backlog 不够,都会触发全量复制,此时主节点要 fork 子进程并传输整份 RDB,内存和网络的开销都不小,尽量避开业务高峰
  • 全量复制期间主节点默认不阻塞(由 fork 出的子进程干活),但 fork 的那一瞬间会有短暂卡顿,实例内存越大越明显
  • 从节点默认是只读的(replica-read-only yes),也可以再挂一层从节点,形成级联复制,用来分担主节点的复制压力
  • 既然是异步复制,主从之间就存在毫秒到秒级的延迟,从节点上可能读到旧数据,对一致性要求高的读请求不要全部丢给从节点

二、实战

我们准备两台机器,一台机器为主,一台机器为从。

1. 安装 Redis

这里就不过多展开。

2. 配置主节点

安装好后配置主节点配置文件。默认路径可能因安装方式而有所不同,默认配置文件位于 /etc/redis/redis.conf 或 /etc/redis.conf:

bash 复制代码
vim /etc/redis/redis.conf

需要修改 bind 和 protected-mode,确保 Redis 能够从外部访问(例如从从节点访问),将 protected-mode 设置为 no,并绑定主节点的 IP 地址。

ini 复制代码
bind 0.0.0.0          # 允许任何 IP 访问
protected-mode no     # 禁用保护模式

修改端口(可选):默认 Redis 使用 6379 端口,如果没有特殊需求,可以不修改。否则,修改为自己需要的端口。

修改配置后记得重启 Redis 服务。

然后检查一下主节点状态 ------ info replication 命令:

bash 复制代码
redis-cli INFO replication

返回信息中,role 应为 master,表示当前是主节点。

3. 配置从节点

打开从节点配置文件:

bash 复制代码
vim /etc/redis/redis.conf

设置主节点:在从节点的配置文件中,添加以下配置,指定主节点的 IP 地址。

设置主节点 + 端口,让从节点能定位到主节点:

ini 复制代码
replicaof 172.22.4.3 6379      # Redis 5.0 版本以上使用
slaveof 172.22.4.3 6379        # Redis 5.0 版本以下使用

禁用保护模式:与主节点类似,关闭保护模式,确保从节点可以接受外部连接。

ini 复制代码
protected-mode no

也是一样的,修改好配置重启服务,然后用 info replication 检查从节点状态:

bash 复制代码
redis-cli INFO replication

返回信息中,role 应为 slave,master_link_status 应为 up,表示从节点正在成功连接到主节点。

后续可以主库写入数据、从库查看来检验主从复制效果,这里不展开。


到这里 Redis 基本的主从复制已经完成,但是有几个问题:

  1. 如果主节点挂了怎么办,怎么完成业务切换与故障转移?
  2. 怎么保证 Redis 的横向拓展性、实时性、高可用性?
  3. 默认情况下,Redis 主从复制不会持久化从节点的数据,怎么实现持久化?

后续的 Redis 哨兵部署、Cluster 集群、Redis 持久化会解答这些问题。

相关推荐
帷幕落秋1 小时前
Mysql主从复制
运维·数据库
暖核1 小时前
MySQL 高级运维核心:备份恢复、主从复制与 MHA 高可用复习总结
运维·数据库·mysql
jackletter1 小时前
linux:systemd之守护进程
linux·运维·服务器·systemd
Ruiery2 小时前
Linux 6.6内核 CPU 深度解析(五):CPU 空闲状态机 cpuidle
linux·运维·服务器
XS0301062 小时前
Nginx 学习指南
运维·nginx
Lsetea3 小时前
OpenSSL verify报invalid CA certificate:basicConstraints与keyCertSign排查
运维·https·ssl证书·openssl·证书链
程序猿老A3 小时前
云服务器怎么配置OSS?
运维·服务器
对讲机数码科普3 小时前
数字集群对讲工程全流程拆解:DMR/ePDT 制式选型、组网落地与运维实战
运维·软件工程
加油yx3 小时前
数据库基础
数据库