架构

memcache缓存雪崩、缓存无底洞、缓存穿透、永久数据被踢现象

2018-12-09  本文已影响5人  不知名的蛋挞

缓存雪崩

当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。

【解决方案】

  1. 在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。

  2. 不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

  3. 做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期(此点为补充)

缓存的无底洞现象

memcached的节点非常多,memcached 连接频率、效率下降,于是增加 memcached 节点,发现因为连接频率导致的问题仍然存在称之为”无底洞现象”。

以用户信息为例,一个用户有很多的信息:user1-age、user1-name、user1-height,当服务器增多,用户的信息也被散落在更多的节点,user1-age在一个节点,user1-name在第二个节点上,user1-height在第三个节点上。

这时候同样是获取这个人的用户信息就要连接多个节点,节点越多要连接的节点也越多。对于memcached的连接数,并没有随着节点的增多,而降低于是问题出现。

【解决方案】

在保存用户信息的时候key键使用共同的前缀进行保存,如使用user1作为键,而不是user1-age为一个键,user1-name为一个键...

缓存穿透现象

所谓的缓存穿透,简单来讲就是查询某些不存在的key时,缓存和数据库查询结果都为空,而空的结果又不被缓存起来,而导致每次查询都去请求数据库层的情况。

缓存不命中,进而导致每次查询都去查询数据库,缓存也就失去了作用,通常表现为服务器负载迅速上升,严重时可能直接宕机。

【解决方案】

  1. 缓存空数据

当第一次查询数据库时,若数据不存在,返回空数据时将其写入缓存,后续查询就不必再去查询数据库了。

  1. 布隆过滤器拦截

问缓存之前,先从布隆过滤器中验证数据是否存在。简单来讲就是使用多个hash函数将一个key映射到一个很长的二进制向量的多个比特位中,类似于hash set。

存在问题:维护复杂,建议只在海量数据的情况下使用。

永久数据被踢现象

缓存数据时已经设为永久有效,却莫名其妙的丢失了,这种现象是因为memcache的惰性删除机制,即LRU最近最少使用删除机制。

当某个单元被请求时,memcache维护一个计数器,通过计数器来判断最近最少被使用的是谁就把谁踢出,即使是永久有效的数据,如果一直没有被使用,而库又满了的情况下,就会把这个永久数据踢出。

【解决方案】

永久数据和非永久数据分开存放。

上一篇下一篇

猜你喜欢

热点阅读