Redis使用时常见的问题

60 阅读3分钟

Redis是在开发中常用的数据库,它被广泛用于缓存,会话存储,消息队列等场景.但在使用中我们也会遇到因为Redis带来的问题.

一.穿透

穿透是访问缓存中没有,数据库中也没有的数据感觉像是穿透了缓存层,直达数据库

穿透常用于作为一种攻击手段,恶意访问服务器致使数据库宕机 解决方法:

  1. 在查一个不存在的数据时,给一个设置一定过期间的Key的数据,存入缓存.这种方法简单粗暴
  2. 用布隆过滤器

实现:先把缓存中的数据的key存入布隆过滤器

然后再查询缓存钱,先判断当前key在布隆过滤器中是可能存在还是一定不存在 如果可能存在查询Redis数据库;如果一定不存在,则直接返回

实现原理:

布隆过滤器是一个大型位数组+多个无偏Hash函数构成

d737ca591ec82841f9948da2087775a2.jpg

步骤:1. 在将数据存入Redis数据库中时,会同时存储Redis的key到布隆过滤器中.key值会通过布隆过滤器对key进行Hash运算,再对位数组长度进行取余,得到一个下标,将该下标设置为1 2. 在查询时,会先按存储到布隆过滤器中的方法,去判断当前的key是否在布隆过滤器中,结果有两种:

  • 可能存在,位数字对应的下标每一个对应值都为1,这种情况下则需要查Redis数据库.就如上图d值一样它的下标为1但是不存在,所以说明当下标都为1也不是一定存在
  • 一定不存在,位数组对应的下标中有一个或多个下标为0说明其值是一定不存在的

二.击穿

击穿是某个热点数据的key突然过期,造成大量请求直达数据库,致使数据库宕机等问题

解决:

  1. 热点数据设置永不过期,并使用定时任务定时更新热点数据.更新数据是先删除当前数据然后再查询将数据写入Redis缓存,更新数据时间一般为凌晨(也就是人查询量少时更新)
  2. 使用限流和降级策略-可以使用sentinel(阿里开源)
  3. 使用分布式锁

三.雪崩

雪崩是Redis缓存中在同一时间点有大量的key同事时过期,使查询数据缓存中没有直达数据库

解决:

  1. 使用分布式锁
  2. 热点数据永不过时
  3. key过期时间使用随机过期时间,即在加入缓存时缓存过期时间假如随机值,使Redis缓存中的数据尽可能的在不同时间过期

四.数据库与Redis的数据一致性

数据一致性分为强一致性和弱一致性(最终一致性)

  • 强一致性:

实现:使用分布式锁

把更新的数据库,删除再缓存的操作当成一个原子性操作,给这个操作加锁,下图是实现流程

570c57b1a1b4c4c69e59924f37ba906e.jpg

  • 弱一致性: 实现:先更新数据库,再删除缓存,在更新数据库后,删除缓存之前,虽然会有短暂不一致的情况,但是最后会一致

还可以基于mysql binlog日志进行异步缓存