应通过redis-py的sentinel类连接哨兵集群,传入哨兵地址列表(如[('127.0.0.1', 26379)]),再调用sentinel.master_for('mymaster')获取自动更新的主节点连接对象,而非直接用redis()连接哨兵端口。

如何用 redis-py 连接哨兵集群并获取主节点连接
Redis 哨兵(Sentinel)本身不处理数据读写,只负责监控和故障转移。客户端必须通过哨兵发现当前主节点地址,再连过去——redis-py 的 Sentinel 类就是干这个的,不是直接连哨兵端口做读写。
常见错误是把哨兵地址当 Redis 实例用,比如传 host='127.0.0.1', port=26379 给 Redis(),结果报 ConnectionError: Error 104 while writing to socket 或直接返回无效响应。
- 初始化
Sentinel时传的是哨兵地址列表,不是 Redis 地址:Sentinel([('127.0.0.1', 26379), ('127.0.0.1', 26380)], socket_timeout=0.1) - 调用
sentinel.master_for('mymaster')获取主节点连接对象(自动重试、自动更新);其中'mymaster'是哨兵配置里sentinel monitor指定的服务名 - 该连接对象是线程安全的,但不要跨进程复用;每次需要操作都应调用
master_for(内部有缓存和刷新逻辑)
为什么用 pipeline + watch 做原子清洗容易失败
想在缓存更新前校验旧值、清洗脏数据,自然想到用 watch + pipeline。但在哨兵环境下,如果执行过程中发生主从切换,watch 的 key 可能已不在新主节点上,导致 WatchError 频发,甚至误删数据。
这不是代码写得不对,而是哨兵故障转移期间,客户端持有的旧主连接会断开,而 redis-py 默认不会在 pipeline 中自动重连或重试 watch。
调用 Cutout.Pro 视觉处理 API 进行背景移除、人像抠图和照片增强,支持文件上传与图片 URL 输入。
- 避免在清洗逻辑中依赖
watch:改用 Lua 脚本封装读-改-写,通过eval一次性提交到当前主节点 - 若必须用
watch,需捕获WatchError并重试整个流程,且重试前调用sentinel.master_for(...).connection_pool.reset()强制刷新连接 - 注意
socket_keepalive和retry_on_timeout参数要设为True,否则网络抖动时连接池可能卡死
清洗任务如何避免重复执行或漏执行
清洗通常由定时任务(如 APScheduler 或 Celery beat)触发,但多个实例同时拉起时,容易出现多节点并发清洗同一份缓存,造成中间态混乱或重复落库。
不能靠应用层加锁(比如用全局变量),因为分布式环境下无效;也不能只依赖 Redis 的 SETNX,因为没考虑任务超时未完成的情况。
- 用
set(key, value, nx=True, ex=300)占坑,value 设为唯一任务 ID(如uuid.uuid4().hex),过期时间略大于单次清洗最大耗时 - 清洗前先
get确认是否自己占的坑;清洗完成后用 Lua 脚本比对 value 再删除,防止误删他人锁 - 关键清洗步骤(如更新缓存+写 DB)建议拆成幂等操作:缓存 key 加版本号,DB 写入带
ON CONFLICT DO NOTHING或INSERT ... ON DUPLICATE KEY UPDATE
缓存更新后如何通知下游服务失效本地副本
很多业务服务会本地缓存 Redis 数据(比如用 functools.lru_cache 或内存字典),Redis 主节点更新了,它们却不知道,导致读到旧值。
Redis 本身不提供“缓存变更广播”,得自己建通道。Pub/Sub 在哨兵下不可靠:订阅连接绑定到某个节点,主从切换后订阅中断且无自动恢复。
- 别用
pubsub订阅;改用“带版本号的 key 更新”+“轮询检查”:下游定期get 'cache_version:xxx',变化则清空本地缓存 - 更稳的方式是走外部消息队列(如 Kafka/RabbitMQ),Redis 更新成功后发一条事件,解耦且支持重试
- 如果坚持用 Redis,可用
SCAN扫描所有cache:*:versionkey 做批量比对,但要注意SCAN不保证一次扫完,需配合游标状态管理
redis.call() 返回值处理不同),这些细节不验证清楚,清洗逻辑上线后反而会放大数据不一致。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










