重试要先分类
重试策略的第一步是按错误分类:可重试的错误(LOADING、TRYAGAIN、连接断开、网络抖动)才值得重试,不可重试的(WRONGTYPE、语法错误)重试只会放大无效流量。可重试的部分要配指数退避与随机抖动,并配合熔断与并发上限,避免重试风暴打垮正在恢复的实例。
基本信息
| 分类 | 可重试与不可重试严格区分 |
|---|---|
| 退避策略 | 指数退避加随机抖动 |
| 保护机制 | 熔断与并发上限 |
| 目标 | 收敛故障,而不是放大 |
| 前提 | 重试前先确认操作是否幂等 |
典型使用场景
- 实例重启加载数据期间返回 LOADING,客户端需要等待后重试
- 主从切换窗口内的连接断开,短暂重试可以自愈
- 集群处于槽迁移或临时状态时返回 TRYAGAIN
- 网络抖动导致的连接重置
- 故障恢复期限制并发,避免把刚恢复的实例再打垮
分类与退避示意
分类与退避示意
# 客户端配置示意:重试上限 3 次,退避采用指数加抖动
# 具体参数名与默认值以所用客户端库的文档为准
# 重试前先做错误分类:
# LOADING 可重试,按退避等待
# TRYAGAIN 可重试,集群临时状态
# WRONGTYPE 不可重试,直接失败并告警
redis-cli INFO persistence | grep -E 'loading' # 观察是否处于数据加载状态
redis-cli INFO replication | grep -E 'master_link_status' # 判断是否处于切换窗口错误与处置
| 错误 | 可重试性 | 处置方式 |
|---|---|---|
| LOADING | 可重试 | 按指数退避等待,避免密集无效请求 |
| TRYAGAIN | 可重试 | 集群临时状态,退避后重试 |
| 连接断开 | 可重试 | 重连后重试,注意操作幂等 |
| WRONGTYPE | 不可重试 | 直接失败并告警,属于代码缺陷 |
| 语法或参数错误 | 不可重试 | 重试没有意义,直接失败 |
| NOSCRIPT | 需特殊处理 | 标准做法是回退到 EVAL 重新加载脚本 |
重试前必须回答一个问题:这个操作是否幂等。非幂等的写操作重试会造成重复写入,需要用唯一标识或 Lua 脚本来保证语义。
没有退避的重试等于另一种故障源:多个客户端会在同一时刻集中重发,把正在恢复的实例再打垮一次。
重试次数与总时长都要有上限。无限重试在故障期间会不断累积请求,占用连接与线程,让恢复变得更慢。