1 缓存穿透:
解释:
向目标系统查询一个必然不存在的数据。有可能是数据真的不存在,也有可能是第三方恶意攻击系统,刻意构建了大量不存在的id来攻击数据库。
如果短时间内极大量的出现缓存穿透,那么系统的数据库将面临极大的压力,甚至宕机。
解决方案:
(1) 存储空值:对不存在的值也在缓存中存储一个特殊的值表示Empty,并为这个id设置一个比较短的缓存过期的时间,这样,这个空的缓存失效之后还能到数据库查询这个id的对应的值是不是已经存在。
(2)提前校验:设置一个较大的bitmap(hashmap)来存储所有可能出现的id,如果请求中的id不在这个map中,直接返回即可。
2 缓存并发:
解释:
当一个系统的并发量很大的时候,缓存中的的一个id的缓存失效,这是如果多个请求同时访问这个id,会造成多个请求同时访问数据库,当请求很多的时候,数据库的压力增大,并且这多个请求还会都去更新一次缓存,造成缓存频繁刷新。
解决方案:
在某个请求发现缓存没有数据时,此时需要获取一个排它锁,由此请求查询数据库并更新缓存。此步骤完成后释放此锁。在此请求操作的过程中,所有其他请求同一id的请求阻塞,待这个更新请求完成后直接从缓存重取数据。
3 缓存失效
解释:
一个id对应的缓存失效只要解决好缓存并发的问题就可以了。但是如果是缓存的失效策略没有定义好,可能造成缓存的集体失效的问题,引发系统的抖动或者雪崩。以下几个原因都可能造成缓存集体失效:
在系统启动批量装载数据缓存时,缓存的过期时间设置得过于一致;或者是在系统访问的高峰期更新或加载了一大批缓存,过期时间一致。
缓存系统出现问题重启或者宕机了。
解决方案:
(1)缓存过期时间尽量散开,可以设置一个范围,比如1-200秒,把缓存的过期时间通过hash散列在这个区间,防止同一时间缓存大量过期。
(2)缓存双写策略,将同一个缓存同时写到两个缓存系统中。memcache有一个参数-b就是可以用来设置backup的缓存,当主缓存失效时还可以通过备份取到数据。
(3)缓存永不过期,在缓存系统中不设置过期时间,所有的缓存数据的更新都通过业务逻辑程序来完成。