主从复制数据延迟

主从复制数据延迟

一句话回答

Redis 主从复制的数据延迟来自网络传输从节点单线程回放网络抖动引起的 backlog 补发,通常在一主一从同机房下延迟为亚毫秒到几毫秒级。


延迟的源头

主节点(写入)         从节点(读取)
     │                    │
     │─── 网络传输 ─────→ │  ① 网络延迟
     │                    │  
     │─── 主线程回放 ────→│  ② 从节点主线程执行命令
     │                    │  
     │← REPLCONF ACK ────│  ③ 心跳确认,更新 offset

① 网络延迟(基础)

同机房  → < 1ms
同城    → 1-5ms
跨地域  → 10-100ms

由网络拓扑决定,无法优化到物理极限以下。

② 从节点回放延迟(核心)

从节点通过一个后台线程接收主节点的数据写入 replication buffer,然后由主线程(事件循环)逐条执行这些命令。

回放速度的影响因素

因素 说明
写入 QPS 主节点 10 万 QPS,从节点也要处理 10 万 QPS 的写入
命令复杂度 SORT、SUNION、大 key 的 LREM 等重命令
从节点自身读负载 读 QPS 也影响从节点主线程的可用时间片
实例大小 大 key 的修改操作占用更多时间

③ 重连滞后

断线重连后即使增量复制,也需要 backlog 中的命令追赶,如果是全量复制则延迟更大。


如何度量延迟

1. 通过 offset 差值(准确)

# 主节点
redis> INFO replication | grep master_repl_offset
master_repl_offset:1234567890

# 从节点
redis> INFO replication | grep slave_repl_offset
slave_repl_offset:1234567850

# 差值 = 40(40 字节,约 1-2 条命令)

2. 心跳时间(粗略)

repl-ping-replica-period 10   # 默认 10 秒

主节点每隔 10 秒向从节点发送 PING,从节点回复 PONG。结合 master_last_io_seconds_ago 可以估计。

3. 业务层判断(最准)

# 主节点写一个带时间戳的 key
TIME_SET  # 获取主节点时间
SET heartbeat:{timestamp} "marker"

# 从节点读取,对比时间差
GET heartbeat:{timestamp}
# timestamp 和当前时间之差 ≈ 复制延迟

常见延迟场景与优化

场景 1:从节点回放跟不上主节点写入

现象:master_repl_offset - slave_repl_offset 持续增大
原因:写入 QPS 太高,从节点回放速度不足

优化

# 1. 检查是否有阻塞操作
redis> CLIENT LIST  # 看从节点是否被阻塞

# 2. 减少从节点读负载
# 如果从节点也对外服务大量读,可以加更多从节点分担读

# 3. 调节 repl-backlog-size 留出缓冲
repl-backlog-size 100mb

场景 2:跨机房延迟

现象:网络 RTT 10ms → 复制延迟始终 ≥ 10ms

优化

# 1. 减少 repl-ping-replica-period,快速检测断线
repl-ping-replica-period 5

# 2. 调整 repl-timeout(需大于 RTT)
repl-timeout 60   # 默认 60 秒,跨机房建议更大

# 3. 级联复制:先同步到就近中继节点
# 主节点(北京) → 中继(上海) → 从节点(上海)

场景 3:大 key 慢操作

# 主节点执行了一个大操作
DEL bigkey  # 耗时 1 秒
# 从节点也要执行同样的 DEL → 也卡 1 秒

优化:使用 UNLINK 替代 DEL(异步删除)。


延迟容忍策略

业务分类

业务类型 延迟要求 方案
用户发帖后立刻看到 < 10ms 同机房部署
计数器统计 < 1 秒 异步读取容忍
排行榜数据 < 5 秒 定期重读
推荐、非实时数据 没关系 正常标准配置

从节点读不到最新数据的处理

# 方案 1:写后读强制走主节点(Redis 无原生支持,上层实现)
def read_with_consistency(key, max_delay_ms=50):
    # 记录写入时间
    # 如果在 max_delay_ms 内写入的 key,强制读主节点
    # 否则读从节点

# 方案 2:WAIT 命令(Redis 3.0+)
redis> SET key value
redis> WAIT 1 1000  # 等待至少 1 个从节点确认,最多等 1000ms
(integer) 1        # 确认的从节点数

面试考点

Q1:Redis 复制延迟极限能到多少?

理论上最大延迟可以到断开连接的 repl-timeout(默认 60 秒)。如果从节点因为网络抖动断连了 30 秒,重连后也可能有 30 秒的数据追赶期。

在生产稳定运行的场景下,同机房延迟通常在 < 5ms

Q2:如何实时监控复制延迟?

# 方法 1:INFO replication 看 offset 差
# 方法 2:Redis 的延迟监控(latency monitor)
redis> CONFIG SET latency-monitor-threshold 100
redis> LATENCY LATEST
# 方法 3:定制 heartbeat key 监控

Q3:从节点复制延迟导致数据不一致怎么处理?

根据业务要求:
- 强一致性业务 → 写到主节点,从主节点读(牺牲扩展性)
- 弱一致性业务 → 正常读写分离,接受毫秒级不一致
- 终极方案 → 使用 WAIT 命令强制等待一定数量的从节点确认写入完成


总结:复制延迟无法完全消除,但可以控制。核心思路是理解延迟来源(网络 + 回放 + 大 key),通过同机房部署、级联复制、WAIT 命令等手段按需管理延迟。

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容