@
imchuncai Q 不 set 会有更严重的并发问题
A 你这个问题,和监听驱逐事件是一个类型,就是你说的竞争态:
“在短时间,高版本事件的不设置(不管是驱逐还是没有不处理 update 事件到 cache ),导致低版本进行覆盖”
所以这里我有一个简单处理方案:
*** 引入一个延迟周期,只更新 cache 已有的 key ,这样避免持久相互驱逐,同时更新并发竞态数据 ***
等于你的 3. CDC 触发更新,redis 不存在该 key,所以不更新,这一步,是有一个延迟周期的,确保 “理论上” 覆盖 1 ,4 这个 T 时间周期
一句话总结,按需写 cache 操作(驱逐、更新触发),延迟一个周期,以便覆盖可能历史低版本(读触发)
---
当然,这不是真正并发安全。
但是如果真要做到一致性,这个是好做的。逻辑如你实现方案
你看:
version=1 ,事件 1 ,4 ,是一个事务
version=2 ,事件 2 ,3 ,是一个事务
这两个事务都是同一个 data ,在这里面做分布式锁就可以了
---
更简单的工程实现:
触发事件然后缓存集中处理,也就是没有并发态:
1. 读触发 cache 更新,触发 event: (read, table, id)
2. 驱逐、写触发 cache 可能更新,触发 event: (write/volatile, table, id)
3. kafka 集中监控,按照 table 分区,同一个 table 事件顺序处理
4. 无论是 1 ,2 事件,从 db 拉去新数据,read 操作直接 cas 更新 cache ,write/volatile 一样,cas and only exists
mysql 在 select by id 这一块,速度高的超过你估计,这些事件都意味着对应 table, id 刚访问过,再次读取都只是从 db 的 cache 获取
无论是 ttl ,volatile 都可控
你看这个实际的工程事件:
1. 无论读写,对业务都没任何影响,分发事件可以搞个异步,goroutine channel with max length ,消费不了直接丢弃
2. cache 动态可控,消费点做逻辑,无论是 ttl 还是 update 事件是否进入 cache