redis缓存失效后如果处理大量请求查询,数据库如何处理

东方游 发布于 2017/02/13 15:55
阅读 1K+
收藏 0

接收到请求后先从缓存查询,查询到就返回,查询不到就从数据库查询,然后放到缓存中,但是现在缓存到期失效了,然后大量的请求都干到了数据库上,数据库的压力一瞬间变高,这样该如何处理,可以用线程吗?而且现在是有多台服务器

加载中
1
阳光test
阳光test

你说的这种是并发量特别大吗?如果只是cache失效并发量不大,那很简单,query db -> put to cache就可以了,这样后续请求又被cache拦掉了,如果是瞬间请求很大,我们可以看一下,如服务器/容器 处理的线程数是多少,然后rt是多少,然后算出db tps/qps是多少,如果并不大,那很有可能是你数据库本身就设计的有问题,如果很大, 那么需要将cache的逻辑和db的逻辑切开,缓存更新异步化,所有请求都直接读cache,不读db就可以了,不过这会稍微有点复杂的,你需要考虑很多额外情况。

0
东方游
东方游

没人看吗- -

0
红魔小贝
红魔小贝

如果怕db压力大的话感觉可以在缓存不存在的时候加同步代码(再判断-读db或读cache)。同步的话不知道作为一个商业应用是不是太奢侈了,感觉延时应该不大。如果缓存不存在的话耗时就是读db的时间,对于进入第一个无缓存条件请求的响应时间是前一个读db+读cache。对于你说的情景在缓存失效时大量并发访问的话可以减小数据库压力的。

0
显峰哥

缓存时效错开

0
redhat9
redhat9
二级cache
0
铲平王
铲平王

能否在缓存失效操作时,取得最新数据再刷新缓存 如果数据库操作该同步串行操作的话可能会降低伸缩性

0
T
TimWong

1. 控制失效时间,避免同时失效。比如写入时,过期时间在一个范围内随机

    ---当然了,这样避免不了redis down机所造成的同时失效(避免down机又是怎么高可用的问题了)

2. 常规的缓存更新,可以加锁。

简单来说,就是当读取缓存失败需要去db读取时,通过加锁保证只有一个请求去db进行读取和更新,其它的请求可以直接返回或等待。

--这种加锁,解决的是某个key失效后,大量请求都同时读取该key的情况(比如全局的计数之类)。如果是上面提到的donw机的场景,那已经是一场”雪崩“了,就要根椐实际场景来操作了。。。

所以,如果是预案,既然是缓存,就要想尽办法,避免整体失效(因为一旦整体失效,而db又无法承受大量请求的话,则只能是降级服务了)

东方游
东方游
谢谢
0
H
HopeFuture

用两个键值对的缓存代替之前的一个,将缓存时间( key-time),和缓存数据( key-data )分离

1.当缓存过期时,第一个线程发现 key-time 没有,则先更新 key-time,

2.然后去查询数据库(或任何比较耗时的数据查询方式),并更新 key-data 的值,

3.当后续线程来获取数据时,虽然第一个还没有从数据库查完并更新缓存,但发现 key-time 存在,会获取旧的数据。

H
HopeFuture
回复 @东方游 : 存在以下几个问题: 1.你用标识的话可能会出现一直等待的问题。 2.其他线程你要设置等待多久合适?对不同的访问设置不同的等待时间?
东方游
东方游
现在想到的方案是如果缓存没有查询到,就向redis中存入一条标识,再进行查库,查库完成之后放到缓存并删除标识,出现大量请求时先去缓存中查询标识,如果查询到标识说明已经在进行数据库查询,这时便进行等待几百毫秒或者几秒,再进行查询 ,不知道这样是否可行
0
mickelfeng
mickelfeng

redis缓存存的哪方面的数据。

东方游
东方游
回复 @mickelfeng : 我题目的意思是缓存到期失效了,然后同时会有大量的请求查询干到数据库中,比如1000个相同的查询同时过来,数据库压力增大,现在是不相给数据库增加压力,又让缓存重新生效
mickelfeng
mickelfeng
变动很少的话不存在。
mickelfeng
mickelfeng
redis缓存过期了。一个请求query+cache,以后请求cache,不存在你说的问题
东方游
东方游
就是查询的数据列表
0
waitliu
waitliu

如果访问量真的到缓存实效都有大量连接同时进来,可以考虑使用redis当数据库用,数据做持久化存储用了。
redis要用备份服务,以确保主服务挂了,备服务提供只读模式降级服务。

返回顶部
顶部