请教一个后端缓存一致性的问题

2022-08-14 16:06:47 +08:00
 ershierdu

问题背景

有一个 app 的后端整体是微服务体系,现在新增一个服务(记为 A )来保存用户对一个开关的选项(也就是 user_id -> pref 的映射)。其他服务可以通过集成 A 的 client 包来实现对 A 接口的调用的,包括查询、修改。现在一共有 B 、C 两个服务在使用。

问题来源

A 存储的东西修改频率非常低,而 B 、C 对 A 的查询会有很多重复的请求,例如 B 会在短时间内多次查询同一个 user_id 的值,造成网络资源的浪费。因此,我们在 A 的 client 包里加了一个带 TTL 的本地缓存。也就是说,B 查询时如果在 client 里的 cache 能命中,就不向 A server 发起请求了。

问题

B 、C 两个服务的本地各有一个缓存。如果我在 C 服务更新了某个 user_id 的值,可以顺便删除 C 的缓存,但 B 这边感知不到变化,在 B 的本地缓存失效前依然在使用旧值。这种场景一般会怎么处理来让 B 的本地缓存也能更新呢?我应该用什么关键词去网上查询?谢谢大家!

P.S.

我一个直观的想法是用消息队列,A 的 server 端在收到修改请求后,向消息队列发消息。B 、C 分别监听消息队列,根据收到的消息来使本地缓存失效。但这样的话需要在 client 实现消费者,是不是太重了?

1589 次点击
所在节点    程序员
7 条回复
lmshl
2022-08-14 16:21:18 +08:00
分布式系统的严格一致性是很难保证的,因为你不可能全局开锁,把更新操作都串行化。
唯一低成本的实现方式是超短 TTL ,比如如果业务允许的前提下,TTL 设置到 10 秒,甚至 5 秒或更短。这样依然可以大幅度减少频繁的重复请求。
fzdwx
2022-08-14 16:21:27 +08:00
都用一个缓存咯,比如 redis 。

缓存过期通知,我这也是用这种 mq 广播。
reter
2022-08-14 16:25:27 +08:00
我建议参考 http 协议自带的缓存机制,etag, if-modified-since 等。每次请求必须都向 A 发送请求,有更改重新获取更改后的内容,没有更改继续使用缓存的内容。
akira
2022-08-14 16:28:45 +08:00
ABC 不都是在服务器端的么,服务器上内网带宽一般都是 GB 级别为单位了,而且内网不计流量费。

网络资源的浪费 这个是从何说起的
zmal
2022-08-14 16:30:47 +08:00
1L 在理。强一致性在这种场景下是非必要的,把 TTL 改成 1s 足够满足需求。
Sendya
2022-08-15 00:29:19 +08:00
1L 在理,还想继续就 MQ 广播吧
zr8657
2022-08-15 16:30:39 +08:00
我用过你说的想法,差不多五六百万用户吧,还算稳定。
如果你那里 ABC 是三个团队,那就不重,最重要的是记好日志用来扯皮,扯皮比记日志都累。

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

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

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

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

© 2021 V2EX