1
wqhui 2021-06-03 17:16:31 +08:00
看业务是不是要求强一致性,还是说最终一致性也可以,强一致性的话代价肯定是大的了
|
2
BBCCBB 2021-06-03 17:17:47 +08:00
没有解决.. 不能容忍的地方我们都查 db.
只要两个地方没有事务. 总是有不一致的窗口存在. |
3
vindac 2021-06-03 17:17:56 +08:00
我们都是缓存定时淘汰,有个服务去更新缓存。。
|
4
zhongpingjing OP @vindac 意思是你们的业务服务自身不会去更新缓存是吗,那如果缓存过期了,会去查 DB 呢还是直接返回 null ?去查 DB 的话,查完会把结果放到缓存中吗?
|
5
abigeater 2021-06-03 18:02:58 +08:00
业务操作对缓存操作不直接写到 DB
服务定时将缓存写到 DB 读取从缓存读取 没有数据从 DB 读取后写到缓存 |
6
zhongpingjing OP @vindac 专门的更新缓存服务,那要如何定位到失效缓存,如何更新它啊,比如缓存 A 过期了,缓存服务就需要去 DB 拉取数据放到缓存中,如何发现缓存 A 失效了,并及时更新它
|
7
raaaaaar 2021-06-03 18:06:18 +08:00 via Android
定时是个思想,大概可以参考下 cache 和内存的做法?没命中时再装载到 cache 里,满了就置换,根据修改位先写会再换什么的
|
8
zhongpingjing OP @abigeater 这样有可能丢失数据
|
9
zhongpingjing OP @raaaaaar 有点听不懂大佬在讲什么[笑哭]
|
10
InkAndBanner 2021-06-03 18:54:54 +08:00
@abigeater 从 DB 读 写到缓存里面不好吗?
|
11
potatowish 2021-06-03 18:58:29 +08:00 via iPhone 1
1.先更新 DB,再删缓存
2.订阅 binlog 日志去单独做更新,比如 canal |
12
fkname 2021-06-03 19:00:07 +08:00
一般有缓存时间兜底
|
13
lsp7572 2021-06-03 19:15:36 +08:00
延时双删了解下
|
16
Croxx 2021-06-03 21:17:11 +08:00 via iPhone
|
17
leafre 2021-06-03 22:00:51 +08:00
删除缓存失败,那就补偿,直到成功为止,单机不一致解决
主从不一致使用选择性读主解决 |
18
ryd994 2021-06-04 07:42:59 +08:00 via Android
双删和后删有什么区别呢?
如果你速度快,别人速度慢,你更新完了别人再去取数据。和你先更新再删缓存又有什么区别? 如果你速度慢,别人速度快。别人把旧值取了,你再去把旧值再删一遍。 提供的保证是基本一样的,就是缓存对 db 的延迟一致性。考虑到写入者挂掉的情况,这甚至不是最终一致性。 你如果要求强一致,那只能用锁了。不那么蛋疼的办法就是:写一个中间件代理。对同一数据的请求由这同一台代理序列化。中间件可以在修改数据库的时候加锁。用本地锁实现了强一致。 但是现在问题就转移到了如何保证对同一数据的请求总是由同一代理处理的问题。看起来是 hash 一下不难。但是你得考虑代理服务器上线离线的情况。 |
19
bthulu 2021-06-04 09:00:36 +08:00 1
不管双删后删, 因网络问题, 都可能导致数据不一致.
如果需要最终一致性, 操作 db 时, 同时在数据库中标记一下需要更新的缓存, 因与 db 操作在同一数据库, 可以保证这里的强一致性. 然后再开定时任务从 db 中捞取需要更新缓存的数据, 去更新缓存, 更新成功后, 再清除此更新标记, 更新缓存失败, 不做处理, 等待下一次任务执行周期就行. |
20
abigeater 2021-06-04 11:33:26 +08:00
@InkAndBanner em..你这里是 从 DB 读,写到缓存吗 还是从 DB 读写到缓存 这个空格分的不够开不知道是哪个意思
1.从 DB 读,写到缓存:我这用定时服务从缓存写到 DB 那如果从 DB 读 就会有个时间差 定时服务还没写进 DB 时被读取就会拿到旧数据 那数据就不一致了 2.从 DB 读写缓存:就是这个意思,只是把从缓存写回到 DB 的压力减少 |
21
abigeater 2021-06-04 11:40:56 +08:00
@zhongpingjing 不会丢吧 边界值可以直接写回 DB 后清缓存和删写回队列 其他的都可以走这个流程 一般 DB 崩都是瞬发的请求导致的 在定时服务写回 DB 可以是频繁的不间断的所以写回 DB 队列应该不会造成堵塞(可能,目前我还没遇过堵塞至少)
|
23
xuanbg 2021-06-04 15:00:44 +08:00
大多数程序员可能没有意识到的是:缓存失效的时序其实并没有辣么重要。假设先读到数据,然后数据被删除,再用这个数据创建了新的数据。在业务上有问题吗?一点问题就没有呀。例如某个客户被删除了,原先基于这个客户的数据失效了吗?并没有啊,所以你们在纠结什么呢?
所以,先删数据库再删缓存就行了。 |
24
zhch602 2021-06-04 16:07:06 +08:00
@lsp7572
@iyaozhen 因为即使用了延迟双删还是有可能不一致,最关键的是 我没听说过哪个业务敢在线上让线程 sleep 个几百毫秒甚至更多 至于资料,你们随便在 google 上搜延迟双删第一页就有文章,直接放个链接 https://www.cnblogs.com/zhouj-happy/p/12616906.html |
25
lsp7572 2021-06-04 17:34:19 +08:00
|
26
lsp7572 2021-06-04 17:41:07 +08:00
另外删除操作可以另起线程,这个是业务方可以考量的虽然会增加编码复杂度
|
27
zhch602 2021-06-04 22:31:55 +08:00 via Android
@lsp7572 解决方法就是没有完美的解决方法,要视业务而定,要强一致只能加锁,最终一致的话延迟双删也是下下策
|
28
JasonLaw 2021-06-10 21:16:36 +08:00
|
29
liian2019 2021-06-15 17:55:02 +08:00
@potatowish 这得单独整一套分布式缓存服务才行,太重了
|