ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

零停机 Redis 模块热升级完整指南:redis-py 故障转移实战

零停机 Redis 模块热升级完整指南:redis-py 故障转移实战 零停机 Redis 模块热升级完整指南redis-py 故障转移实战【免费下载链接】redis-pyRedis Python client项目地址: https://gitcode.com/GitHub_Trending/re/redis-py凌晨两点大促前夜运维清单上只剩最后一项Redis 模块热升级。但业务还在跑DBA 排不出维护窗口硬重启一次就是几分钟的缓存穿透。这次升级不必停下来做——用 redis-py 的 multidb 多数据库客户端把主备两个实例接进同一个客户端整个过程零停机。读完这篇你能把升级模块从一次停机演练变成 10 分钟内的流量切换。拆解 redis-py 故障转移的三条防线 ⚡切换零停机的底气来自客户端里三件互相配合的机制请求永远只发给健康节点、故障转移策略决定切给谁、健康检查策略决定谁算健康。熔断器请求如何只发给健康节点每个数据库实例背后都有一个熔断器Circuit Breaker它是节点可用性的闸门。熔断状态为 CLOSED 表示该节点当前可用OPEN 表示已被隔离不再接收请求HALF_OPEN 表示正在试探它是否恢复。健康检查每隔几秒跑一轮结果直接驱动闸门开合# redis/multidb/circuit.py 中的三种状态 # CLOSED节点健康可以接收业务请求 # OPEN节点已被隔离请求不会发给它 # HALF_OPEN试探中试探成功则回到 CLOSED if database.circuit.state CBState.CLOSED: # 业务流量只会路由给这类节点 pass所以升级某个节点在客户端视角里很简单让它熔断OPEN它就不再分到任何请求。WeightBasedFailoverStrategy权重即优先级redis/multidb/failover.py 里的WeightBasedFailoverStrategy负责挑出当前活跃节点。规则直白所有节点按权重从高到低排队第一个熔断器为 CLOSED 的节点胜出def database(self) - SyncDatabase: for database, _ in self._databases: # 权重降序遍历 if database.circuit.state CBState.CLOSED: return database # 第一个健康节点即活跃节点 raise NoValidDatabaseException(No valid database available)主库权重 10、备库权重 5 时正常运行流量走主库主库熔断后备库立刻补位。注意这里的权重不是流量配比而是优先级序号——谁大谁优先。Redis 健康检查策略三种判定规则redis/asyncio/mudb 的 healthcheck 模块 提供三种策略区别只在一轮探针里允许失败几次。以 3 次 PING 探针为例策略判定适合场景HEALTHY_ALL默认3 次全部成功才算健康关键业务宁严勿松HEALTHY_MAJORITY允许失败 1 次多数成功即健康网络偶发抖动的环境HEALTHY_ANY只要 1 次成功就算健康可用性优先的非关键链路from redis.asyncio.multidb.healthcheck import HealthCheckPolicies cfg MultiDbConfig( databases_config[...], health_check_policyHealthCheckPolicies.HEALTHY_MAJORITY, )升级场景下备库刚加载完新模块冷启动可能慢一拍HEALTHY_MAJORITY比默认的HEALTHY_ALL更不容易误判。升级前准备三步配置多数据库客户端所有配置只做一次之后你的业务进程一直用同一个客户端对象调用代码不用改。配双库连接。用DatabaseConfig描述每个节点weight决定优先级主 10 备 5from redis.multidb.config import MultiDbConfig, DatabaseConfig cfg MultiDbConfig( databases_config[ DatabaseConfig(from_urlredis://primary:6379/0, weight10), DatabaseConfig(from_urlredis://backup:6379/0, weight5), ], )定探针参数。health_check_probes3表示每轮检查打 3 次 PINGhealth_check_delay0.5是探针间隔 0.5 秒——太短会放大误判太长则故障发现迟钝health_check_interval5是每 5 秒跑一轮完整检查。cfg MultiDbConfig( databases_config[...], health_check_probes3, health_check_delay0.5, health_check_interval5, )定切换行为。failover_attempts10与failover_delay12表示所有节点都不可用时客户端会按 12 秒间隔最多再试 10 次而不是立刻抛错auto_fallback_interval120表示每 120 秒尝试切回权重最高的健康节点——这正是原主库升完自动收回流量的开关。默认值都定义在 redis/multidb/config.py 里全量参数说明见 docs/geographic_failover.rst。from redis.multidb.client import MultiDBClient client MultiDBClient(cfg)完整升级演练四步走完一次 Redis 模块热升级假设此刻 primary权重 10在扛流量backup权重 5是 Active-Active 架构下的实时副本切流量不丢数据。第 1 步升级备库在 backup 上卸载旧模块、加载新版本模块。因为备库权重低、平时不分请求这次操作不影响业务。升完先验证对新版本模块发几条真实查询确认行为符合预期。第 2 步把流量切到备库backup_db next(d for d, _ in client.get_databases() if d.weight 5) client.update_database_weight(backup_db, 20) # 权重 5 - 20超过主库权重一变且备库熔断器为 CLOSED客户端自动把活跃节点切到 backup。primary 从此停止收请求成为安全升级区。第 3 步升级原主库对 primary 执行同样的模块升级。期间它的健康检查失败、熔断器变 OPEN但没有任何请求在飞——这正是零停机的含义每一步被升级的节点都恰好不在服务请求。第 4 步原主库重新入池client.update_database_weight(backup_db, 5) # 备库权重降回 5 # primary 权重 10 保持最高等健康检查通过即可收回流量primary 升完模块、连续 3 次探针通过后熔断器回到 CLOSEDauto_fallback_interval到期时流量自然切回backup 成为新备库。 至此完成一轮双库轮流升级业务全程无感。踩坑清单与上线前验证切换机制上线前最容易被低估的是下面三个坑。别让网络抖动误触发切换三个参数共同决定切换的脾气health_check_delay0.5秒太激进、叠加HEALTHY_ALL太严格一次 1 秒的网络抖动就可能把健康节点误判下线。 生产建议抖动多的环境用HEALTHY_MAJORITY 3 次探针 1 秒延迟让单次丢包被多数投票抹平。反过来health_check_interval别超过 30 秒否则真实故障的发现时间会被拉长。盯住升级过程接上切流事件监听切换发生时客户端会广播ActiveDatabaseChanged事件把它接进日志系统升级窗口里每次切流都有据可查class LogFailoverListener(EventListenerInterface): def listen(self, event: ActiveDatabaseChanged): print(f切流: {event.old_database} - {event.new_database})上线前做故障注入测试不要等生产事故来验证切换机制。参考 tests/test_multidb/test_failover.py 的思路在预发环境写个最小演练把主库熔断器手动置为 OPEN断言failover_strategy.database()返回备库再置回 CLOSED验证update_database_weight能把流量切回去。这套测试跑通后演练当天的切换只是把 mock 换成真故障。写在最后multidb 的故障转移与健康检查把Redis 模块升级不停机拆成了四个可以独立验证的小动作每一步都有熔断状态和事件日志背书这是零停机方案能落地的真正原因。下一步可以试试接入LagAwareHealthCheck让健康判定再细一层——如果你有踩坑经验欢迎在评论区分享我会持续跟进这套机制的演进。【免费下载链接】redis-pyRedis Python client项目地址: https://gitcode.com/GitHub_Trending/re/redis-py创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表