ARTICLE DETAIL

资讯详情

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

Redis 模块热升级指南:用 redis-py 多数据库故障转移做到零停机

Redis 模块热升级指南:用 redis-py 多数据库故障转移做到零停机 Redis 模块热升级指南用 redis-py 多数据库故障转移做到零停机【免费下载链接】redis-pyRedis Python client项目地址: https://gitcode.com/GitHub_Trending/re/redis-py周五晚八点你要给线上 Redis 升一个模块手指悬在重启键上不敢按——一重启几百条连接当场断掉。其实不用停。redis-py 的多数据库multidb故障转移机制能让这次 Redis 模块热升级做到零停机让备用节点顶上去、原主节点慢慢换业务全程无感。先给你一张地图主备节点和流量是怎么切的一句话讲清平时只有权重最高的那个健康节点在扛流量另一个节点闲着待命升级时把流量切到备节点主节点腾出手来换模块换完再切回来。整个切换由客户端在应用进程内完成不依赖你改 DNS、不依赖外部编排。下面这张图里左侧的入口对应你的业务进程右侧多个DB对应 redis-py 配置的多台 Redis。平时请求只落到其中一台一旦这台不可用客户端在本地就把指向换到另一台上层代码完全不用改。机制拆解故障转移怎么配它解决什么问题当正在扛流量的节点挂了或你主动要把它摘下来升级谁来顶故障转移策略就是挑替补的人。redis-py 默认用基于权重的策略把节点按权重从高到低排好从头找第一个健康的熔断器处于 CLOSED 状态就选中它。权重高的优先权重低的当备胎。class WeightBasedFailoverStrategy(FailoverStrategy): def database(self) - SyncDatabase: for database, _ in self._databases: if database.circuit.state CBState.CLOSED: return database raise NoValidDatabaseException(No valid database available)选中之前的挑只是第一步。挑完之后还有一层执行器在兜底如果一次没挑到健康节点它会按failover_delay默认 12 秒反复重试failover_attempts默认 10 次期间对外抛临时不可用而不是直接报错。这意味着一次性的网络抖动不会立刻把你打崩。源码在 redis/multidb/failover.py。一个容易忽略的细节每个节点背后挂着一个熔断器状态在 CLOSED健康→ OPEN熔断→ HALF_OPEN试探恢复之间流转。节点被判 OPEN 后会先等一个grace_period默认 60 秒再进入 HALF_OPEN 试探避免刚恢复又被打死。这正是为什么备节点能安全接管的底层保证。机制拆解健康检查策略怎么选它解决什么问题故障转移的前提是这个节点到底还能不能用。健康检查就是在给每个节点做体检并把结果翻译成熔断器的开/合。redis-py 后台每隔health_check_interval默认 5 秒对所有节点做一轮探测默认用PING探活。真正可调的是判定策略——它决定几次探测里失败几次才算不健康策略判定规则适用场景HEALTHY_ALL全部探测成功才算健康最严关键业务宁可误切也不带病运行HEALTHY_MAJORITY多数成功即可3 探 2 过默认平衡点容忍偶发抖动HEALTHY_ANY只要一次成功就算健康最松可用性优先能扛就扛默认是HEALTHY_ALL。以全部成功策略为例它连续发health_check_probes默认 3次探测中间失败一次就立刻判为不健康把熔断器打开async def _execute(self, health_check, database): client await self.get_client(database) for attempt in range(health_check.health_check_probes): if not await health_check.check_health(database, client): return False if attempt health_check.health_check_probes - 1: await asyncio.sleep(health_check.health_check_delay) return True探测次数、间隔health_check_delay默认 0.5 秒、超时都能调。策略与探测项都定义在 redis/asyncio/multidb/healthcheck.py配置入口在 redis/multidb/config.py。实操走查一次真实的模块热升级前提先说死两台节点数据必须保持同步备节点是主节点的副本或至少模块数据一致。否则流量切过去读到的是旧数据无缝就成空话。下面按时间线走一遍配置一个双节点客户端长这样from redis.multidb.client import MultiDBClient from redis.multidb.config import MultiDbConfig, DatabaseConfig from redis.asyncio.multidb.healthcheck import HealthCheckPolicies config MultiDbConfig( databases_config[ DatabaseConfig(weight10, client_kwargs{host: db-primary, port: 6379}), DatabaseConfig(weight5, client_kwargs{host: db-backup, port: 6379}), ], health_check_policyHealthCheckPolicies.HEALTHY_ALL, ) client MultiDBClient(config)第一步给备节点换模块。主节点weight10继续扛全部流量备节点weight5此时不处理业务。你只在备节点上升级 Redis 模块、重启它。为什么安全备节点本来就没流量崩了也没人看见。要盯模块是否加载成功、副本同步是否追平master_link_status、主从偏移量归零。第二步把流量切到备节点。备节点升完、健康检查转绿后用权重把它扶正——调高备节点权重让它超过主节点客户端的故障转移策略就会自动把活跃数据库切过去。也可以直接调client.set_active_database(backup_db)手动晋升。为什么安全切换前客户端会先对该节点做一轮健康检查不健康会直接拒绝。要盯切换日志里活跃数据库从 primary 变成 backup以及旧连接的关闭、pub/sub 自动重订阅是否完成。第三步给原主节点补升级。现在主节点变成空闲的备胎了。对它升级模块、重启跟第一步同样的动作。为什么安全它已经不在扛流量随便折腾。要盯升级后它作为备节点能否正常跟上同步。第四步回切 / 回挂。原主节点升完把权重调回或调update_database_weight让流量回到原本的主人身上整个集群完成一代模块升级。此时备节点又回到待命状态随时应对下一轮。要盯回切后活跃数据库指向是否恢复、是否有报错率回升。避坑清单健康检查策略别一把梭HEALTHY_ALL。它最严格节点稍有抖动就切。升级窗口内你不想被一次偶发超时打回原形可按业务容忍度降到HEALTHY_MAJORITY但关键路径如带缓存扣款请保持严格宁可切过去也不带病。转移参数别设得太激进。failover_delay默认 12 秒、重试 10 次是为宁可多等也别反复横跳设计的。别为了快把它改成秒级——网络抖一下你就来回切反而放大故障面。同理grace_period默认 60 秒是给恢复节点留的冷静期别关。盯监控别盯日志肉眼。切换动作客户端会打出unreachable / reachable again的告警日志但真正该看的是可观测指标活跃数据库指向、错误率、以及 geo failover 事件记录源码见 redis/multidb/command_executor.py。给每次切换配个告警别等用户投诉才发现切错了。上线前先把故障演练跑一遍。别等到周五晚上才第一次见它。参考 tests/test_multidb/ 里的用例主动把主节点拉黑验证摘主→切备→回挂整条链路都按预期走再谈零停机。写在最后把换模块拆成备节点先换、流量切走、原节点补换、回切四步redis-py 用故障转移和健康检查把每一步的切换都自动化你只需要按时间线操作并盯住监控。下次升级手指可以不用悬在重启键上了。下期想聊聊这套机制之外的坑pub/sub 在切换时怎么自动重订阅、以及事务跨节点时为什么需要小心。【免费下载链接】redis-pyRedis Python client项目地址: https://gitcode.com/GitHub_Trending/re/redis-py创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表