【Redis】主从复制Day9

写在前面

在实际生产环境中,单机Redis面临两个核心问题:性能瓶颈和单点故障。主从复制是Redis实现高可用的基础,它不仅解决了数据冗余备份问题,还为读写分离、故障转移提供了可能。今天我们深入理解Redis主从复制的原理与实践。

文章目录


一、为什么需要主从复制?

1.1 单机Redis的局限性

实际场景:某电商平台Redis单机承载了100万QPS,在双十一大促时,CPU使用率达到100%,响应延迟从1ms飙升到100ms,严重影响了用户体验。

单机Redis面临的问题:

问题 说明
性能瓶颈 单机处理能力有限,无法水平扩展
单点故障 服务器宕机后服务不可用
数据丢失风险 硬件故障可能导致数据丢失
读写压力 所有请求都打到一台服务器

1.2 主从复制的价值

主从复制带来的好处:

  • 数据冗余:实现数据热备份

  • 读写分离:主节点写,从节点读,分担压力

  • 高可用基础:为哨兵和集群提供基础

  • 故障恢复:主节点故障时可切换到从节点

    复制代码
                  ┌─────────────┐
                  │   Client    │
                  └──────┬──────┘
                         │ Write
                         ▼
                  ┌─────────────┐
                  │   Master    │
                  │   (写+读)    │
                  └──────┬──────┘
                         │ 复制
           ┌─────────────┼─────────────┐
           ▼             ▼             ▼
    ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
    │   Slave-1   │ │   Slave-2   │ │   Slave-3   │
    │    (只读)    │ │    (只读)    │ │    (只读)    │
    └─────────────┘ └─────────────┘ └─────────────┘
           ▲             ▲             ▲
           │             │             │
      ┌────┴────┐   ┌────┴────┐   ┌────┴────┐
      │  Read   │   │  Read   │   │  Read   │
      └─────────┘   └─────────┘   └─────────┘

二、主从复制原理

2.1 复制流程概述

经验之谈:理解复制流程对于排查主从同步问题至关重要,特别是全量同步和部分同步的区别。

Redis主从复制分为三个阶段:

  1. 连接建立阶段:从节点连接主节点
  2. 数据同步阶段:全量同步或部分同步
  3. 命令传播阶段:主节点持续发送写命令

2.2 全量同步(SYNC)

全量同步发生在:

  • 从节点第一次连接主节点
  • 从节点断开时间过长,无法部分同步

全量同步流程:

复制代码
┌──────────────┐                              ┌──────────────┐
│    Slave     │                              │    Master    │
└──────┬───────┘                              └──────┬───────┘
       │                                             │
       │  1. PSYNC ? -1                              │
       │────────────────────────────────────────────>│
       │                                             │
       │  2. FULLRESYNC <runid> <offset>             │
       │<────────────────────────────────────────────│
       │                                             │
       │                    3. 执行BGSAVE生成RDB      │
       │                       (同时记录写命令到缓冲区) │
       │                                             │
       │  4. 发送RDB文件                              │
       │<────────────────────────────────────────────│
       │                                             │
       │  5. 加载RDB文件                              │
       │                                             │
       │  6. 发送缓冲区的写命令                        │
       │<────────────────────────────────────────────│
       │                                             │
       │  7. 同步完成,开始命令传播                    │
       │                                             │

2.3 部分同步(PSYNC)

Redis 2.8引入部分同步,减少全量同步的开销。

部分同步条件:

  • 从节点之前同步过主节点
  • 主节点runid未变化
  • 复制偏移量在复制缓冲区范围内

核心概念:

概念 说明
runid 主节点的唯一标识,每次重启会变化
offset 复制偏移量,记录同步位置
repl_backlog_buffer 复制缓冲区,环形结构,默认1MB
复制代码
┌─────────────────────────────────────────────────────────┐
│                  repl_backlog_buffer                     │
│  ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐ │
│  │ cmd1│ cmd2│ cmd3│ cmd4│ cmd5│ cmd6│ cmd7│ cmd8│ ... │ │
│  └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ │
│                          ▲                              │
│                          │                              │
│                    master_offset                        │
└─────────────────────────────────────────────────────────┘

如果 slave_offset 在缓冲区范围内,可以部分同步

2.4 命令传播

同步完成后,主节点持续将写命令发送给从节点:

redis 复制代码
# 主节点执行写命令
SET key1 value1

# 主节点将命令传播给从节点
# 从节点执行相同的命令保持数据一致

三、主从复制配置

3.1 配置方式

方式一:配置文件

conf 复制代码
# redis.conf(从节点配置)
replicaof 192.168.1.100 6379

# Redis 5.0之前使用
# slaveof 192.168.1.100 6379

# 从节点只读
replica-read-only yes

# 主节点密码
masterauth "your_password"

方式二:命令行

redis 复制代码
# 在从节点执行
REPLICAOF 192.168.1.100 6379

# 取消主从关系
REPLICAOF NO ONE

3.2 重要配置参数

参数 说明 默认值
replicaof 主节点地址和端口 -
masterauth 主节点密码 -
replica-read-only 从节点只读 yes
repl-diskless-sync 无盘复制 no
repl-backlog-size 复制缓冲区大小 1MB
repl-timeout 复制超时时间 60s
repl-disable-tcp-nodelay 禁用TCP_NODELAY no

3.3 查看复制状态

redis 复制代码
# 查看主从复制信息
INFO replication

# 主节点返回示例
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.1.101,port=6379,state=online,offset=1024,lag=0
slave1:ip=192.168.1.102,port=6379,state=online,offset=1024,lag=0
master_repl_offset:1024
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1024

# 从节点返回示例
# Replication
role:slave
master_host:192.168.1.100
master_port:6379
master_link_status:up
slave_repl_offset:1024

四、主从切换

4.1 手动主从切换

踩坑提醒:手动切换需要谨慎操作,确保数据同步完成后再切换,否则可能丢失数据。

步骤:

redis 复制代码
# 1. 在新主节点执行,停止复制
REPLICAOF NO ONE

# 2. 在其他从节点执行,指向新主节点
REPLICAOF new_master_ip 6379

# 3. 验证主从状态
INFO replication

4.2 读写分离配置

应用层需要区分读写请求:

shell 复制代码
# 主节点地址(写操作)
MASTER_HOST=192.168.1.100
MASTER_PORT=6379

# 从节点地址(读操作)
SLAVE_HOSTS=192.168.1.101:6379,192.168.1.102:6379

读写分离架构:

复制代码
┌─────────────┐
│ Application │
└──────┬──────┘
       │
       ▼
┌─────────────┐
│  读写分离层   │
│ (客户端/代理) │
└──────┬──────┘
       │
   ┌───┴───┐
   │       │
   ▼       ▼
Write    Read
   │       │
   ▼       ▼
Master   Slave

五、踩坑提醒

踩坑提醒:复制延迟问题

问题描述:

主从复制是异步的,从节点的数据可能落后于主节点,读取从节点可能获取到过期数据。

延迟产生原因:

  1. 网络延迟
  2. 从节点性能不足
  3. 主节点写入压力过大
  4. 大key复制耗时

解决方案:

方案 说明
监控延迟 使用INFO replication查看lag
读写分离策略 强一致性读走主节点
优化网络 使用内网、万兆网卡
控制大key 避免存储大key
增加带宽 提高复制带宽限制
conf 复制代码
# 调整复制带宽限制
repl-backlog-size 64mb        # 增大复制缓冲区
client-output-buffer-limit replica 256mb 64mb 60

踩坑提醒:主从切换数据丢失

问题描述:

异步复制场景下,主节点宕机时,从节点可能还没收到最新的写命令。

解决方案:

  1. 配置合理的min-replicas-to-write
  2. 使用哨兵或集群实现自动故障转移
  3. 业务层实现重试机制
conf 复制代码
# 至少有1个从节点才能写入
min-replicas-to-write 1
min-replicas-max-lag 10

踩坑提醒:全量同步阻塞

问题描述:

主节点执行BGSAVE生成RDB时,如果内存数据量大,会消耗大量CPU和内存,影响性能。

解决方案:

  1. 使用无盘复制
  2. 控制单实例内存大小
  3. 在低峰期添加从节点
conf 复制代码
# 开启无盘复制
repl-diskless-sync yes
repl-diskless-sync-delay 5

六、主从复制优化

6.1 配置优化

conf 复制代码
# 增大复制缓冲区
repl-backlog-size 256mb

# 开启无盘复制
repl-diskless-sync yes

# 复制超时时间
repl-timeout 120

# 从节点TCP_NODELAY
repl-disable-tcp-nodelay no

# 限制复制缓冲区大小
client-output-buffer-limit replica 512mb 128mb 60

6.2 架构优化

优化项 说明
主从节点同机房 减少网络延迟
从节点不少于2个 保证数据冗余
合理分配内存 预留内存给复制
监控复制延迟 及时发现问题

七、面试高频考点

考点1:主从复制的流程?

答案:

  1. 连接建立:从节点连接主节点,发送PSYNC命令
  2. 全量同步:主节点执行BGSAVE生成RDB,发送给从节点
  3. 缓冲同步:主节点将同步期间的写命令发送给从节点
  4. 命令传播:主节点持续将写命令发送给从节点

PSYNC优化:

  • 从节点记录runid和offset
  • 重连时发送PSYNC runid offset
  • 如果offset在缓冲区范围内,只同步增量数据

考点2:如何减少主从复制延迟?

答案:

  1. 网络优化:主从部署在同机房,使用高速网络
  2. 配置优化:增大复制缓冲区,开启无盘复制
  3. 架构优化:控制单实例内存,避免大key
  4. 监控告警 :监控slave_repl_offsetmaster_repl_offset差值
  5. 读写策略:强一致性读走主节点

考点3:主从复制是同步还是异步?

答案:

Redis主从复制是异步的:

  • 主节点执行写命令后立即返回,不等待从节点确认
  • 通过repl_backlog_buffer记录写命令
  • 从节点异步获取并执行写命令

影响:

  • 优点:主节点性能不受从节点影响
  • 缺点:主节点宕机可能丢失未同步的数据

考点4:SYNC和PSYNC的区别?

答案:

对比项 SYNC PSYNC
Redis版本 2.8之前 2.8之后
同步方式 只支持全量同步 支持全量和部分同步
断线重连 需要全量同步 可能只需部分同步
性能
资源消耗

八、参考资料

Redis官方文档 - Replication


九、互动话题

  1. 你的生产环境主从架构是如何设计的?遇到过什么问题?
  2. 如何监控主从复制延迟?延迟超过多少需要告警?
  3. 主节点宕机后,如何实现自动故障转移?

欢迎在评论区分享你的经验和见解!


下一期预告:Day10 - Redis哨兵机制,敬请期待!

相关推荐
8Qi81 小时前
LeetCode 208:实现 Trie(前缀树)—— Java 题解 ✅
java·算法·leetcode·二叉树·tire树
Wenzar_1 小时前
GeoHash+Redis Streams实时围栏系统实战
java·数据库·redis·junit
侯盛鑫1 小时前
理解 RocksDB IngestExternalFile
数据库·后端
可乐ea1 小时前
【知识获取与分享社区项目 | 项目日记第 20 天】search_after 游标分页:解决 Elasticsearch 深分页稳定性问题
java·大数据·elasticsearch·搜索引擎·全文检索
字节高级特工1 小时前
C++11(二) 革新:引用折叠与lambda表达式
java·开发语言·c++·算法
萨小耶1 小时前
[Java学习日记11】聊聊深拷贝和浅拷贝
java·开发语言·学习
ECT-OS-JiuHuaShan1 小时前
辩证函数,渡劫代谢:时势造英雄,英雄发神经
数据库·人工智能·机器学习
Mr.朱鹏1 小时前
基于 postgres_fdw 的跨库查询方案
java·数据库·spring boot·sql·spring·postgresql
敲个大西瓜1 小时前
Java并发实用干货
java