redis布隆过滤器与四个缓存问题
创始人
2024-06-01 10:44:47
0

目录

    • 布隆过滤器
        • 定义
        • 特性
        • 使用场景
          • 解决缓存穿透的问题
          • 黑白名单校验
        • 底层原理
          • 哈希冲突案例
          • 添加key
          • 查询key
        • 总结
    • 四个缓存问题
      • 缓存雪崩
        • 定义
        • 解决方案
      • 缓存穿透
        • 定义
        • 解决方案
        • 方案一
        • 方案二(guava实现)
          • 代码案例
          • 源码分析
        • 方案三(RedisSon实现)
            • 代码实现
        • 方案四(直接安装redis插件,应用层解决方案)
          • 编译安装Rebloom插件
          • docker安装
      • 缓存击穿
        • 定义
        • 解决方案

布隆过滤器

定义

它实际上是一个很长的二进制数组+一系列随机hash算法映射函数,主要用于快速的判断一个元素是否在集合中.
布隆过滤器的初始状态

他的判断结果并不是百分之百准确的

特性

  • 高效的插入和查询,占用空间少,返回的结果是不确定性的
  • 一个元素如果判断结果为存在的时候元素不一定存在,但是判断结果为不存在的时候则一定不存在
  • 布隆过滤器可以添加元素,但是不能删除元素.因为删除元素会导致误判率增加
  • 误判只会发生在过滤器没有添加过的元素,对于已经添加过的元素不会发生误判.

因为可能发生hash冲突

使用场景

解决缓存穿透的问题

把已经存在数据的key存放到布隆过滤器中,相当于在redis前面再加一层拦截过滤.
当有新的请求时,先到布隆过滤器中查询是否存在,如果布隆过滤器不存在该条数据则直接返回,如果布隆过滤器中已存在,才去查询redis缓存,如果redis没有再去查询mysql

黑白名单校验

直接判断值在不在布隆过滤器里面

底层原理

哈希冲突案例
public static void main(String[] args) {System.out.println("Aa".hashCode());System.out.println("BB".hashCode());}
添加key

使用多个hash函数对key进行hash运算得到一个整数索引值,对位数组长度进行取模运算得到一个位置,每个hash函数都会得到一个不同的位置,将这几个位置都置为1就完成了add操作
添加key的图示
添加n个key
添加一个key

查询key

只要有其中一位是0就表示这个key不存在,如果都是1(都是布隆过滤器就返回存在),但是不一定就代表存在这对应的key.
因为只要是hash函数就存在hash冲突,哪怕是采用了多个hash函数也有可能会跟其他的多个key值hash出来的值冲突,所以不能确定一定存在
查询误判示意图:
查询误判示意图

总结

  • 有是有可能有,无就是一定无
  • 使用时最好不要让实际元素数量远大于初始化数量
  • 当实际元素数量超过初始化数量时,应该对布隆过滤器进行重建,重新分配一个size更大的过滤器,再将所有的历史元素批量add进去
  • 优点
  • 高效的插入和查询
  • 占用空间很少
  • 缺点
  • 不能删除元素(因为删除元素会导致误判率的增加,因为hash冲突同一个槽位对应多个对象的信息,你删除一个元素很可能把其他的也删除了)
  • 存在误判率(hash冲突,不同的数据对象可能会出来相同的hash值)

四个缓存问题

缓存雪崩

定义

redis主机挂了,redis全盘崩溃(或者缓存中有大量数据同时过期)

解决方案

  • redis缓存集群实现高可用
    • 主从+哨兵
    • Redis Cluster
  • ehcache本地缓存 + Hystrix或者阿里sentinel限流降级
  • 开启redis持久化机制aof/rdb,尽快恢复缓存集群

缓存穿透

定义

一般情况下,先查询缓存redis是否有该条数据,缓存未命中时,在查询数据库.当数据库也不存在该条数据时,每次查询都要访问数据库,这就是缓存穿透.它带来的问题就是当有大量的请求查询数据库本身就不存在的数据时,就会给数据库带来压力,甚至是直接拖垮数据库

解决方案

  • 方案1:空对象缓存或者缺省值
  • 方案2:google布隆过滤器guava解决缓存穿透
  • 方案3:redis布隆过滤器解决缓存穿透

方案一

就是缓存一个空值或者业务上定义的缺省值在redis里面缓存返回(每次换id就不好用了 而且会导致大量的无用key堆积)

方案二(guava实现)

代码案例
public static final int _1w = 10000;public static final int size = 100 * _1w;public static double fpp = 0.03;/*** 入门demo*/public void bloomFilter() {BloomFilter filter = BloomFilter.create(Funnels.integerFunnel(), 100);System.out.println(filter.mightContain(1));System.out.println(filter.mightContain(2));filter.put(1);filter.put(2);System.out.println(filter.mightContain(1));System.out.println(filter.mightContain(2));}/*** 误判率演示和源码分析*/public void bloomFilter2() {BloomFilter filter = BloomFilter.create(Funnels.integerFunnel(), size);for (int i = 0; i < size; i++) {filter.put(i);}ArrayList list = new ArrayList<>(size);for (int i = 0; i < size; i++) {if (filter.mightContain(i)) {list.add(i);}}System.out.println("存在的数量" + list.size());ArrayList arrayList = new ArrayList<>(10 * _1w);for (int i = size + 1; i < size + 100000; i++) {if (filter.mightContain(i)) {System.out.println(i + "被误判了");arrayList.add(i);}}System.out.println("误判的数量" + arrayList.size());}public static void main(String[] args) {new GuavaBBloomFilterDemo().bloomFilter2();}
 
源码分析

guava布隆过滤器新建

当你的误判率fpp越低,需要占用的bit数组就越长,对值进行hash计算的hash函数就越多,这样的话能更加避免hash冲突的情况发生,用空间和时间来换取准确率,guava默认设置是0.03,个人用的话最低也就建议到0.01,再低的话导致程序变慢就得不偿失了.

方案三(RedisSon实现)

代码实现
public static final int _1w = 10000;public static final int size = 100 * _1w;public static double fpp = 0.01;static RedissonClient redissonClient;static RBloomFilter rBloomFilter;static {Config config = new Config();config.useSingleServer().setAddress("redis://8.131.64.231:16678").setDatabase(0).setPassword("liang#0601");redissonClient = Redisson.create(config);rBloomFilter = redissonClient.getBloomFilter("phoneList", new StringCodec());rBloomFilter.tryInit(size, fpp);rBloomFilter.add("10086");redissonClient.getBucket("10086", new StringCodec()).set("chinamobile10086");}public static String getPhone(String id) {String result;if (rBloomFilter.contains(id)) {RBucket rBucket = redissonClient.getBucket(id, new StringCodec());result = rBucket.get();if (result != null) {return "result form redis:" + result;} else {result = getByMysql(id);if (result == null) {return null;}redissonClient.getBucket(id, new StringCodec()).set(result);}return "result form mysql:" + result;}return null;}public static String getByMysql(String id) {return "10086mysql";}public static void main(String[] args) {String phone = getPhone("10086");System.out.println(phone);redissonClient.shutdown();}

方案四(直接安装redis插件,应用层解决方案)

编译安装Rebloom插件

编译安装
编译安装

docker安装

常用操作命令

默认的误判率是0.01 默认的bit数组是100

缓存击穿

定义

热点key突然失效了,导致大量的请求直接打到了MySQL上面

解决方案

  • 互斥更新(在第一个线程进来拿数据的时候,如果发现redis里面没有就用互斥锁锁住,更新进入redis之后在放开锁)
  • 随机退避
  • 双缓存结构解决
  • 开启两块缓存,主A从B,先更新B再去更新A,严格按照这个顺序
  • 先查询主缓存A,A没有再去查询从缓存B
  • 注意更新和查询的顺序要倒过来,这样就能避免有时间差

两个主从缓存差异化失效时间,在你删除缓存的时候就不会缓存击穿

缓存问题总结图

相关内容

热门资讯

王者定位怎么关安卓系统,轻松实... 你是不是也和我一样,对王者荣耀这款游戏爱得深沉呢?不过,有时候游戏里的设置让人头疼,比如安卓系统的王...
树莓派安卓系统流畅,打造便携式... 亲爱的读者们,你是否曾想过,将树莓派与安卓系统结合,会擦出怎样的火花呢?今天,就让我带你一起探索这个...
安卓系统智能机顶盒,引领家庭娱... 你有没有想过,家里的电视也能变得智能起来?没错,就是那个陪伴我们多年的老电视,现在也能摇身一变,成为...
安卓系统很差了吗现在,性能优劣... 最近是不是有不少朋友在讨论安卓系统的问题呢?有人说它越来越差了,也有人觉得它还是那个熟悉的“老朋友”...
安卓系统uc安装包,Andro... 你有没有发现,手机里的安卓系统越来越强大了?今天,咱们就来聊聊这个话题——安卓系统中的UC安装包。你...
安卓系统谷歌能删吗,谷歌能否删... 你有没有想过,那个一直陪伴你手机生活的安卓系统,它背后的谷歌爸爸,是不是也能被你随意删掉呢?这可不是...
安卓系统会不会更耗电,解析其功... 你有没有发现,手机用着用着,电池就有点不给力了?尤其是那些用安卓系统的手机,有时候感觉电就像流水一样...
安卓系统中无效目录,安卓系统无... 你有没有遇到过在安卓系统中,明明文件夹就在那里,但是就是找不到的情况?别急,今天就来给你揭秘安卓系统...
国产安卓机哪个系统好用,探寻最... 你有没有想过,国产安卓机哪个系统最好用呢?这可是个让人纠结的问题,毕竟每个系统都有它的特色和亮点。今...
安卓系统cpua9,引领性能与... 你有没有发现,最近你的安卓手机运行得是不是比以前顺畅多了?这可多亏了那个强大的安卓系统CPUA9啊!...
安卓系统usb驱动程序,功能、... 你有没有遇到过这种情况:手机里存了那么多宝贝照片和视频,想传输到电脑上保存,结果电脑却像个小顽皮,死...
安卓操作系统怎么关闭,轻松关闭... 手机里的安卓操作系统是不是有时候让你觉得有点儿烦呢?别急,今天就来手把手教你如何轻松关闭安卓操作系统...
追星手机壳推荐安卓系统,盘点热... 你有没有发现,现在追星族们对手机壳的热爱简直到了疯狂的地步?没错,就是那种能让你一秒变身偶像迷妹的手...
ios系统用安卓系统游戏下载软... 你有没有想过,明明是iOS系统的手机,却想玩安卓系统的游戏?这可不是什么天方夜谭,现在就有这么神奇的...
安卓高系统怎么用美化,打造专属... 亲爱的安卓用户们,你是不是也和我一样,对手机系统美化情有独钟呢?想要让你的安卓手机焕然一新,变得个性...
安卓系统怎么开夜间模式,安卓系... 亲爱的手机控们,你是不是在夜晚使用安卓手机时,眼睛感到有些不适?别担心,今天我要给你揭秘一个超级实用...
王者安卓系统用苹果人脸,一场视... 你知道吗?最近在手机圈里可是掀起了一股不小的波澜呢!那就是王者安卓系统竟然用上了苹果人脸识别技术!是...
安卓444怎么升级系统,轻松迈... 你那安卓444的小家伙是不是已经有点儿落伍了?别急,今天就来给你详细说说怎么给它来个系统升级,让它焕...
安卓系统raw修图软件,探索安... 你有没有发现,手机拍照越来越方便了,但有时候拍出来的照片还是不够完美呢?别急,今天就来给你安利几款安...
安卓系统的王者切换苹果,从安卓... 你知道吗?最近身边的朋友圈里掀起了一股热潮,那就是安卓系统的王者们纷纷切换到苹果阵营。这可真是让人大...