有一个 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 的本地缓存也能更新呢?我应该用什么关键词去网上查询?谢谢大家!
我一个直观的想法是用消息队列,A 的 server 端在收到修改请求后,向消息队列发消息。B 、C 分别监听消息队列,根据收到的消息来使本地缓存失效。但这样的话需要在 client 实现消费者,是不是太重了?
1
lmshl 2022-08-14 16:21:18 +08:00
分布式系统的严格一致性是很难保证的,因为你不可能全局开锁,把更新操作都串行化。
唯一低成本的实现方式是超短 TTL ,比如如果业务允许的前提下,TTL 设置到 10 秒,甚至 5 秒或更短。这样依然可以大幅度减少频繁的重复请求。 |
2
fzdwx 2022-08-14 16:21:27 +08:00
都用一个缓存咯,比如 redis 。
缓存过期通知,我这也是用这种 mq 广播。 |
3
reter 2022-08-14 16:25:27 +08:00 via Android
我建议参考 http 协议自带的缓存机制,etag, if-modified-since 等。每次请求必须都向 A 发送请求,有更改重新获取更改后的内容,没有更改继续使用缓存的内容。
|
4
akira 2022-08-14 16:28:45 +08:00
ABC 不都是在服务器端的么,服务器上内网带宽一般都是 GB 级别为单位了,而且内网不计流量费。
网络资源的浪费 这个是从何说起的 |
5
zmal 2022-08-14 16:30:47 +08:00
1L 在理。强一致性在这种场景下是非必要的,把 TTL 改成 1s 足够满足需求。
|
6
Sendya 2022-08-15 00:29:19 +08:00
1L 在理,还想继续就 MQ 广播吧
|
7
zr8657 2022-08-15 16:30:39 +08:00
我用过你说的想法,差不多五六百万用户吧,还算稳定。
如果你那里 ABC 是三个团队,那就不重,最重要的是记好日志用来扯皮,扯皮比记日志都累。 |