Redis缓存
# Redis缓存
# 缓存三大问题
# 缓存穿透
缓存穿透就是指要查询的数据在Redis,Mysql中都不存在,大量这样的查询会让数据库直面大量的流量,根本没有经过缓存这一层,对数据库造成了巨大的压力,可能直接就被这么多请求弄宕机了。
# 解决方法
首先要做的就是对请求进行一些参数校验,比如有要查询id为1的请求。
缓存无效key
具体做法是在查询到数据库里没有后,在Redis里缓存一个空的数据,并设置过期时间,
这种方式可以解决请求的 key 变化不频繁的情况,如果黑客恶意攻击,每次构建不同的请求 key,会导致 Redis 中缓存大量无效的 key 。很明显,这种方案并不能从根本上解决此问题。如果非要用这种方式来解决穿透问题的话,尽量将无效的 key 的过期时间设置短一点比如 1 分钟。
一般这样设计 key :表名:列名:主键名:主键值
。
布隆过滤器
布隆过滤器是一种数据结构,他可以帮我们判断数据是否存在于某个数据集合中。
具体做法是:把所有可能存在的请求的值都存放在布隆过滤器中,当用户请求过来,先判断用户发来的请求的值是否存在于布隆过滤器中。不存在的话,直接返回请求参数错误信息给客户端,存在的话才会走下面的流程。
布隆过滤器的原理
# 缓存击穿
缓存穿透是对于热点Key来说的,热点数据,当缓存失效的一瞬间,所有的请求都被下放到数据库去请求更新缓存,数据库被压垮。
# 解决方法
加锁
基本思想就是多个请求都想要查询数据库跟新缓存时候,必须要先获取锁,获取到的才能去查询数据库然后跟新缓存,其他请求只能等待。等到缓存重建成功时,就能查询缓存的数据返回了
逻辑过期时间
基本思想是不设置过期时间,只多添加一个字段,作为过期的时间,当查询时候发现过期,就会单独启一个线程去重建缓存(也是要获取锁的),然后本线程就直接返回过期的数据,其他线程来了发现过期,也尝试获取锁,重建缓冲,获取失败,就直接返回过期数据,重建缓存成功后,其他线程就能获取最新的数据了。
# 缓存雪崩
同一时间内,大量的key同时过期,导致数据库直面大量的压力。或者Redis服务挂了。
对于 Redis 挂掉了,请求全部走数据库,也属于缓存雪崩,我们可以有以下思路进行解决:
事发前:实现 Redis 的高可用(主从架构+Sentinel 或者 Redis Cluster),尽可能避免 Redis 挂掉这种情况。
事发中:万一 Redis 真的挂了,我们可以设置本地缓存(ehcache)+ 限流(hystrix),尽量避免我们的数据库被干掉。
事发后:Redis 持久化,重启后自动从磁盘上加载数据,快速恢复缓存数据。
针对 Redis 服务不可用的情况:
- 采用 Redis 集群,避免单机出现问题整个缓存服务都没办法使用。
- 限流,避免同时处理大量的请求。
针对热点缓存失效的情况:
- 设置不同的失效时间比如随机设置缓存的失效时间。
- 设置多级缓存。
总结就是,设计之初就应该为key设置不同的过期时间,搭建高可用的Redis集群,配合限流,和多级缓存。防止mysql面临较大压力
参考