缓存策略
常见的缓存方面的问题有:缓存雪崩、缓存穿透、缓存击穿。
名词解释
缓存雪崩
即大量的key在某个时刻,一起失效了(很可能这些key是同时导入的,并且加了相差无几的失效时间),这时大量访问直接奔数据库去了,导致数据库挂掉。
缓存击穿
击穿一般形容尖利的东西,从某一点穿过。缓存击穿也是一样,指某个key迎来了大量请求,然而这个key失效了,导致所有访问直接奔数据库去了,导致数据库挂掉。
缓存穿透
穿透可以理解为面粉穿过筛子,非常多的点。缓存穿透就是指,大量key迎来了大量请求,并且这些key都不存在,导致所有访问直接奔数据库去了,导致数据库挂掉。
彼此的区别
雪崩和穿透的区别在于:虽然都是海量key,但雪崩的key是失效了,而穿透的key根本不存在。
击穿和穿透的区别在于:击穿的key只有一个或很少,穿透的key有海量。
处理方式
雪崩
处理的办法也比较简单:
- 加入key的时候,失效时间加上一个随机数,随机数分布越大,雪崩概率越低。
- 使用集群,可以将数据分布到不同的物理机器上。
- 如果这种大量导入的key具有一定规律,比如每天早上2点导入,那么失效时间大于24小时即可。
- 双备份,两个缓存互相备份。
击穿
击穿的处理方式就是:
- 保证热点key不失效,或者失效时间巨长。
- 热点多备几个只读节点
- 适当过滤一些不正常的访问
- 限制访问的频率和线程数
穿透
处理方式:
- 不存在的key,也保存起来,值就设置一个null,30秒失效,缺点当然就是浪费空间时间。
- 以redis为例子,防止某类id的穿透攻击,就是做个bitmap,直接过滤掉不存在的id。
- 高端的就是布隆过滤器(我也没用过),但是原理也是一样的,先把不存在的key过滤掉。
缓存淘汰方式
数据库有变化,对缓存的处理一般是删除,而不是更新。
而更新手段比较靠谱的是更新前删除。
考虑到高并发,很可能更新后,还是会存在更新前的缓存,就需要再清一次。
考虑到高高高并发,甚至再更新数据库后,需要稍等几秒,再清一次缓存。