更新服务器缓存如何合并相同请求?

2016-10-08 20:47:14 +08:00
 aiqier

我们有一个布置了多台的服务,服务从 redis 集群中获取数据,一个 key 对应一个 value ,如果没有,则会从三方接口获取并进行计算后先返回给调用方再写入缓存。三方接口的响应时间大概 2s

现在有一个问题是,三方接口是收费的,如果此时多个请求同时到达而且计算出来的 key 都相同,会都发现缓存没有,而都会去调用第三方接口。这很浪费资源,因为只需要调用三方接口一次就够了。在服务本身对请求做合并的方式效果并不好,因为服务布了多台。

如何能 hold 住这些其实在请求一个资源的多个请求链接,只出发一次更新缓存的逻辑,然后在数据返回后,统一还给它们。

2707 次点击
所在节点    Java
11 条回复
julyclyde
2016-10-08 20:51:20 +08:00
自旋锁
master
2016-10-08 20:53:47 +08:00
key 没有值 但是已经有服务器去要值的时候 可以标记个占坑
其他服务器看到坑占了 可以等待一定时间再去取 如果坑被占了超过一定时间 还是没有值
那就当前的机器重新把坑占了(更新占坑的信息) 然后去取值喽
fwrq41251
2016-10-08 21:15:03 +08:00
一个想法。当服务用 key 去取发现没有的时候,先随便往里面写一个值,然后再调第三方接口,等调用完毕再把真实的内容替换之前随便写的值。
reus
2016-10-08 21:31:40 +08:00
上锁,刚好有 redis ,可以做分布式锁
6IbA2bj5ip3tK49j
2016-10-09 09:08:42 +08:00
用 futureTask 占坑
sun1991
2016-10-09 10:28:27 +08:00
不能由 cache 服务去申请付费 API 吗?
julyclyde
2016-10-09 11:10:52 +08:00
@sun1991 那无非是把合并动作推到 cache 层去了而已,还是得做的
aiqier
2016-10-09 11:29:05 +08:00
@master
@fwrq41251
@xgfan
@reus
@julyclyde
合并请求是这个需求的一部分吧,关键是要能够在有数据后唤醒那些 hold 住的链接。
6IbA2bj5ip3tK49j
2016-10-09 11:31:39 +08:00
@aiqier get()阻塞住了,也可以加一个超时。
chenqh
2016-10-09 11:32:27 +08:00
不懂
不是
if not in cache:

with lock:
if not in cache:
get from api
这种逻辑吗?
lrh3321
2016-10-09 14:02:27 +08:00
https://www.v2ex.com/t/308349
之前看过这么个帖子,和你的需求貌似很相近。

利用 redis 的 setnx 设置标记,成功设置了标记的线程去调用第三方接口。

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

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

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

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

© 2021 V2EX