缓存雪崩

假如有多条数据在同一时间存入Redis,可以给失效时间加一个随机数,让它们不会在同一时间失效。
针对热点数据可以设置更长的失效时间,直到它们不再热为止。
如果是Redis集群部署,可以将热点数据均匀分布在不同的Redis库中,这样可以防止因一台Redis宕机而全部热数据失效的问题。
对同一ip做请求频率的限制,例如每一秒限制100个请求,每一分钟限制1000个请求,具体的频率限制根据你的系统业务特点和用户群体而定,注意一个公司几百号人的ip可能是一样的,得允许同一个公司的多人同时发起请求。这一点是一个网站必须要做的,防止缓存雪崩、击穿、穿透,包括其它的防范都能用上。
缓存穿透
产生原因:

解决方法:
校验请求参数,明显不存在或者不合法的参数直接返回错误,如id为-1的参数。
访问权限校验,如果无权访问则直接返回错误。
当查询到数据库中不存在的数据(例如id为1001的参数)时,也在Redis中做标识,例如存一个空值到Redis中,下次再访问时就知道此数据是不存在的,不用再查数据库了。这里需要注意的是,当新增了数据时记得清一次缓存里的标识,例如新增了id为1001的数据时,要把Redis中id为1001的无数据标识给清理掉。
对同一ip做请求频率的限制,例如每一秒限制100个请求,每一分钟限制1000个请求,具体的频率限制根据你的系统业务特点和用户群体而定,注意一个公司几百号人的ip可能是一样的,得允许同一个公司的多人同时发起请求。这一点是一个网站必须要做的,防止缓存雪崩、击穿、穿透,包括其它的防范都能用上。
Redis在4.0版本推出了 module 的形式,可以将 module 作为插件额外实现Redis的一些功能。官网推荐了一个 RedisBloom 作为 Redis 布隆过滤器(Bloom Filter)的 Module,这个也能很好的防止缓存穿透的发生,它的原理也很简单就是利用高效的数据结构和算法快速判断出一个Key是否在数据库中存在,若不存在直接返回就好了,若存在就去查DB刷新KV,再返回数据。
缓存击穿
产生原因:

解决方法:
把热点数据的缓存失效时间设置长一点,直到它不热为止。
对于单个ip或者单个用户访问单个id数据的频率做限制,例如每1秒最多请求30次,具体频率根据系统业务特点和用户情况而定。注意一个公司几百号员工的ip是一样的,得允许同一个公司的多人同时发起请求。这样可以防止攻击用户反复用同一个id暴力攻击。
加Redis锁,当缓存失效时只允许一个请求去访问数据库和更新缓存,其它请求等待Redis缓存中的数据。具体的PHP代码实现我会在后面的文章中分享,关注YiluPHP的微信公众号,不错过精彩的干货分享。
总结




