一、明明按顺序发的命令,为什么Redis里的数据顺序乱了? 上周四凌晨,我们的实时风控系统突然告警用户行为事件的时间戳出现乱序,导致风控规则误判。 这个系统每秒处理约2万条事件,采
一、明明按顺序发的命令,为什么Redis里的数据顺序乱了?上周四凌晨,我们的实时风控系统突然告警——用户行为事件的时间戳出现乱序,导致风控规则误判。 这个系统每秒处理约2万条事件,采用Redis Pipeline批量写入以降低网络开销。 问题来了: 代码里明明按时间顺序将事件推入Pipeline,但Redis里却出现了时间戳倒序的数据。 你是不是也认为Pipeline只是"批量发送命令"? 我也曾这么想,直到这次踩坑。 二、现象复现:Pipeline的"伪顺序保证"先看当时的错误代码(Python示例,其他语言同理):
理论上,sorted_events是按时间升序排列的,写入Redis后ZRANGE user_events 0 -1应该得到有序结果。 但实际观测到部分数据乱序,例如:
三、根因:TCP/IP栈与Redis线程模型的合谋1. 网络层乱序尽管客户端通过单个TCP连接顺序发送命令,但TCP/IP协议栈可能存在:
2. Redis服务端线程竞争即使命令按序到达Redis:
与单条命令不同,Pipeline将多个命令作为一个"批处理单元"提交。 如果其中某个命令执行较慢(例如遇到大Key),可能导致后续命令先被执行完成。 四、解决方案:用WATCH+MULTI实现真·原子顺序正确写法需要满足两个条件:
实测对比(10万条数据,单位:ms):
五、避坑清单:Pipeline使用的3条军规关键区别:
顺序敏感场景慎用纯Pipeline 监控Pipeline的乱序率
区分"网络批量化"和"原子性" 六、最后的选择:什么时候该用Pipeline?经过这次教训,我的决策树变成: 允许最终一致:用纯Pipeline(性能最优)
如果 需要强顺序:WATCH+MULTI+Pipeline(性能折衷) 如果 需要强原子性:Lua脚本(功能最稳) |
2021-04-08
2021-10-03
2024-09-30
2021-07-26
2019-10-11