数据库与缓存的一致性问题的两个疑问

2022-08-19 17:57:34 +08:00
 mitu9527
首先,这里不讨论 Binlog 方案。

其次,基于我对该问题的理解,准备用以下实现:
1 )先更新数据库,再删除缓存。
2 )通过延时双删解决不一致问题,这里借助消息队列实现了异步的延时双删,以加快吞吐量。
3 )通过消息队列实现重试,以解决第二步 删除缓存失败 的问题。

最后,我有两个想问的问题:
1 )除了侵入了业务代码和引入消息队列会引发的问题以外,上面的方案有啥问题么?
2 )下列两种伪代码实现,哪种是对的?错在哪里?


// 伪代码 1
// 更新数据库
updateDB();
// 第一次删除缓存,同步
result = deleteCache(key);
if (false == result) {
// 失败
sendMessageToMQToDeleteCacheWithoutDelay(key);
}
// 第二次删除缓存,异步且延迟
sendMessageToMQToDeleteKeyWithDelay(key, delay);


// 伪代码 2
// 更新数据库
updateDB();
// 第一次删除缓存,同步
deleteCache(key);
// 即使上面的第一次删除缓存操作失败了,也什么都不做,继续向下执行
// 第二次删除缓存,异步且延迟
sendMessageToMQToDeleteCacheWithDelay(key, delay);
2476 次点击
所在节点    程序员
26 条回复
sy20030260
2022-08-19 22:36:51 +08:00
关乎业务代码的问题,脱离了具体业务场景来做技术选型,无异于纸上谈兵

回归实际业务场景:引入 cache 解决什么问题?引入 cache 之后期望穿透到 DB 的压力有多少?能否接受短时间内的数据不一致?可以的话最长能容忍多久的不一致?如果确实出现不一致会导致什么问题(用户体验下降 or 资损)...具体业务中还会有更多细节。不回答这些问题,实在无法做技术选型

在我遇到的大多数业务场景中,如果已经采用 cache-aside ,大多数情况下就是个逻辑简单、高并发、RT 敏感的读接口。这种业务场景对数据一致性并没有那么强的需求,设置个短一点的缓存过期时间就是了,甚至都不需要引入队列(徒增架构复杂度

在使用 cache-aside 的情况下,还需要纠结两种队列用法之间细微差异的业务场景,可能是我见识太少,实在没见过。如果是真实业务场景的话还希望 OP 分享下,让我也长长见识
mitu9527
2022-08-19 22:46:47 +08:00
@sy20030260 我平时也不会引入消息队列,只是简单更新以下数据库,然后删除缓存。虽说讨论有些空乏,但是并不代表问题不存在啊,所以才拉出来讨论啊,不用实现强一致性,但是不是还是应该尽可能更完善一点呢。
Jooooooooo
2022-08-19 22:55:54 +08:00
你把每一步网络交互都假想会失败再看方案

比如第一种方案里, updateDB 你这边超时了, 但是数据库成功了, 还要不要往下走? 如何去补偿.

另外还有并发的问题

比如第一种方案里, 线程 1 updateDB1 成功之后, 线程 2 紧接着去执行 updateDB2, 和 deleteCache2, 然后线程 1 deleteCache1 才执行, 会不会造成数据错乱呢?
tairan2006
2022-08-19 23:00:06 +08:00
@mitu9527 你说的这个并不影响最终一致,只要缓存过期时间设置的不太长就没关系。
sy20030260
2022-08-19 23:30:23 +08:00
@mitu9527 这个问题当然是存在的,一个更「完善」的方案当然也是值得追求的。但可能我没表达清楚,核心问题在于:没有具体业务场景作为前提,是没法衡量哪种方案更完善的。方案 A 可能在某场景下是完善的,但在其他场景下可能就远远不如方案 B ,而且甚至起到反效果。这种实际业务中是很常见的。

啥叫前提啊?你读取一个数,前提是你要知道进制;你问现在几点,前提是你得告诉我啥时区;你求个坐标,前提是你得知道参考坐标系。不给你参考坐标系你会求坐标吗,不会的话就别绕开业务场景谈什么更完善的技术方案
RedBeanIce
2022-08-20 10:44:24 +08:00
如同 21 楼说的那样,关乎业务代码的问题,脱离了具体业务场景来做技术选型,无异于纸上谈兵

我目前所写到的项目,基本上 binlog 的方案可以解决一致性的问题,
如果你想更进一步,,我没有想过,我去看代码去了,溜溜。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/874053

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX