面试redis篇-02缓存穿透

原理

        例: 一个get请求:api/news/getById/1

面试redis篇-02缓存穿透_第1张图片

缓存穿透:查询一个不存在的数据,mysql查询不到数据也不会直接写入缓存,就会导致每次请求都查数据库

解决方案一

缓存空数据,查询返回的数据为空,仍把这个空结果进行缓存

优点

简单

缺点

消耗内存,可能会发生不一致的问题

解决方案二

布隆过滤器

面试redis篇-02缓存穿透_第2张图片

优点

内存占用较少,没有多余key

缺点

实现复杂,存在误判

布隆过滤器

bitmap(位图):相当于是一个以(bit)位为单位的数组,数组中每个单元只能存储二进制数0或1

布隆过滤器作用:布隆过滤器可以用于检索一个元素是否在一个集合中。

面试redis篇-02缓存穿透_第3张图片

  • 存储数据:id为1的数据,通过多个hash函数获取hash值,根据hash计算数组对应位置改为1
  • 查询数据:使用相同hash函数获取hash值,判断对应位置是否都为1
  • 误判率:数组越小误判率就越大,数组越大误判率就越小,但是同时带来了更多的内存消耗。
  • 面试redis篇-02缓存穿透_第4张图片

提问与回答

面试官:什么是缓存穿透 ? 怎么解决 ?

回答

        缓存穿透是指查询一个一定**不存在**的数据,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到 DB 去查询,可能导致 DB 挂掉。这种情况大概率是遭到了攻击。
        解决方案的话,我们通常都会用布隆过滤器来解决它

面试官:好的,你能介绍一下布隆过滤器吗?

回答

        布隆过滤器主要是用于检索一个元素是否在一个集合中。我们当时使用的是redisson实现的布隆过滤器。
        它的底层主要是先去初始化一个比较大数组,里面存放的二进制0或1。在一开始都是0,当一个key来了之后经过3次hash计算,模于数组长度找到数据的下标然后把数组中原来的0改为1,这样的话,三个数组的位置就能标明一个key的存在。查找的过程也是一样的。
        当然是有缺点的,布隆过滤器有可能会产生一定的误判,我们一般可以设置这个误判率,大概不会超过5%,其实这个误判是必然存在的,要不就得增加数组的长度,其实已经算是很划分了,5%以内的误判率一般的项目也能接受,不至于高并发下压倒数据库。

你可能感兴趣的:(缓存,面试,redis)