高并发情况下,缓存失效,怎么让多个请求只有一个请求去取数据,其他请求阻塞?
发布于 7 年前 作者 JerrysShan 4423 次浏览 来自 问答

在高并发情况下,多个相同的请求同时从缓存中取数据,缓存没命中,然后都穿透缓存去查询数据库,这样请求都打到数据库上了,对数据库造成了压力,还会造成频繁的缓存更新。

我的想法是设置一个锁,只有一个请求拿到锁,然后去取数据,从数据库查询到数据后,写入缓存,然后其他请求从缓存中取数据,关键是怎么让其他请求阻塞,想到redis的订阅-发布,但是没有具体的思路,怎么实现?请各位大神解惑。。。。。。

7 回复

1.png

这是我的设计思路

假设服务器处于空闲状态,并发100个请求获取某个未缓存的资源。

在服务端收到第一个请求之后,这时候没有锁,直接查询缓存,发现缓存未命中,就查数据库,并且更新缓存,返回。

而后面的99个请求,在服务端收到的时候,发现对应的资源已经上锁了,只能等待ing…

等待到第一个请求结束释放锁的时候,后面的99个请求再查询缓存,发现命中缓存,直接返回缓存内容。

以上愚见,请大神指教

@axetroy 谢谢,很清晰的流程图,我想明白怎么让其他99个请求等待或者挂起,一直轮询吗?

缓存机制有多种 写通 write through 回写 write back

可以看一下朴灵老师的深入浅出node.js 里面有解决方法

来自酷炫的 CNodeMD

轮询肯定不是好的方式,可以使用 EventEmitter ,当第一个请求没结束释放锁的时候,其余请求都往事件上注册一个回调函数,当第一个请求结束释放锁的时候依次调用这些回调函数来通知后面的99个查询请求。 具体代码可以参考朴灵老师的深入浅出node.js

我认为这种情况下数据缓存不应该考虑,不就是多一百个请求打到数据库吗?你上锁费功夫,还不如优化下数据库。

另外,你这种情况下,加锁会影响qps

回到顶部