缓存一般作为RDS的前置组件,将常用的资源缓存,用来减少RDS的读取压力,也是诸多系统常用的一种方案,如果允许访问缓存失败直接访问数据库,然后再将数据回写到缓存中,那么就会存在缓存击穿的问题,
缓存击穿:缓存中的数据未被命中,进而请求直接对数据库进行查询,当大量的类似查询瞬间出现,就会出现数据库的压力爆炸甚至引起数据库的雪崩,本质就是一种缓存失效引发的极端问题
如何应对这种情况?
在很多面试过程中碰到这样的问题,给出答案:不给缓存击穿的机会
首先不允许跨过缓存直接访问数据库,在缓存中及认为数据可以被访问,否则则认为访问的数据不存在,
接下来就是RDS和缓存的同步问题,保证数据最终会呈现给用户,但是有延迟,功能的延迟和系统雪崩的风险选择,个人比较倾向于后者,
这种方案将数据的查询完全依赖缓存,一旦缓存挂掉,基本系统也就over了,这就依赖缓存的高可用部署了,采用集群或者多集群的方式,提高系统的可用性,剩下的就是和RDS一样的问题,比如防攻击,数据切片等
另外还有一种方案,加锁的方式,对于同一个key进行枷锁,当key 不命中的时候,需要去数据库中去查询然后回写到缓存中,查询已经回写的操作进行加锁,粗暴一点 可以用synchronized直接加锁,最坏的情况,jvm中,某个key的请求的请求 全部block,另外可以用分布式锁的方案,当发现key不命中时向redis中添加一个lock_key,添加方式使用setnx指令,这样同一个key的请求只有一个成功,设置成功的请求,进行查询回写操作,设置失败的请求,建议直接进行返回,不要等待,比较一个服务器的连接数是有限制的,如果太多请求等待的话 会影响其他的正常业务
已有 0 人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐