读写分离怎么落地
主从复制最常见的用途之一是读写分离:写请求走主库,读请求分摊到从库,从而提升整体读吞吐并降低主库压力。路由位置有两种选择:客户端侧(业务代码或框架维护主从两套连接),或代理层(中间件、负载均衡、服务网格)。关键约束是:从库数据天然落后主库,任何「必须读到最新值」的读取都不能放到从库,否则在复制延迟或切换窗口内会读出倒退的数据。
基本信息
| 写入目标 | 主库端点 |
|---|---|
| 读取目标 | 从库池,按复制延迟与负载选择 |
| 主要风险 | 读到旧值、切换期间数据不一致 |
| 实现方式 | 客户端路由、代理层转发、服务网格 |
| 前置条件 | 从库保持只读保护,避免误写 |
典型使用场景
- 读多写少的业务(列表、详情、报表)把读压力分摊到从库
- 写后立即读的流程必须回主库,例如下单后立刻查询订单状态
- 从库选择策略:按复制延迟过滤,延迟超标的从库临时摘除
- 切换演练时验证读路径的恢复速度
- 与缓存配合:先查缓存,未命中再按路由规则读后端
路由与健康检查
路由与健康检查
# 配置示意:master 负责写,replicas 负责读
# master: 10.0.0.11:6379
# replicas: [10.0.0.12:6379, 10.0.0.13:6379]
redis-cli -h 10.0.0.12 INFO replication | grep master_link_status
redis-cli -h 10.0.0.12 INFO replication | grep master_last_io_seconds_ago # 延迟过滤依据
redis-cli -h 10.0.0.11 INFO replication | grep -E 'connected_slaves|slave0'
redis-cli -h 10.0.0.12 INFO replication | grep slave_read_only读写路径对比
| 维度 | 主库 | 从库 |
|---|---|---|
| 数据新鲜度 | 始终最新 | 可能落后一个复制延迟 |
| 承载能力 | 单点,写能力受单线程限制 | 可水平扩展读能力 |
| 故障影响 | 切换期间写入短暂失败 | 单台故障可被其他从库承接 |
| 误用后果 | 读压力集中到主库 | 读到旧值,业务状态出现回退 |
业务上先区分「必须最新」与「可容忍旧值」两类读,前者永远走主库。这个分类一旦确定,一致性管理会简单得多,也不会在事后反复争论某条查询该走哪边。
从库列表不要写死在代码里:扩容、维护、切换都会改变拓扑,静态列表容易漏更新,表现为部分请求持续失败,而日志里只看到连接错误。
从库的只读保护应当保持开启,避免读路径上意外产生写入。那部分数据既不会被同步,也不会进入基于主库的备份,属于「写了但随时会消失」的状态。