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
  • 注意更新和查询的顺序要倒过来,这样就能避免有时间差

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

缓存问题总结图

相关内容

热门资讯

飞车手游ios系统跟安卓系统,... 你有没有发现,最近手机上的一款飞车手游特别火呢?这款游戏不仅画面精美,操作流畅,而且玩法多样,吸引了...
安卓平板显示系统不兼容,安卓平... 你有没有遇到过这种情况?买了一款心仪的安卓平板,满怀期待地想要体验各种精彩应用,结果却发现有些应用显...
安卓系统安装破解app病毒,安... 你知道吗?在安卓系统上安装破解版的APP,听起来是不是有点刺激?但别高兴得太早,这背后可是隐藏着不少...
安卓版桌面操作系统,探索安卓桌... 你有没有想过,你的安卓手机桌面操作系统,其实就像是一个小小的魔法世界呢?在这个世界里,你可以随意布置...
安卓系统要怎么截屏,轻松实现屏... 亲爱的手机控们,你是不是也经常想要截取手机屏幕上的精彩瞬间呢?安卓系统的截屏功能可是非常实用哦!今天...
安卓forpc系统下载,轻松实... 你有没有想过,手机上的安卓系统竟然也能在电脑上运行?没错,这就是安卓forpc系统的魅力所在!今天,...
普通汽车cd改安卓系统 你有没有想过,你的普通汽车CD播放器其实也可以升级成安卓系统呢?没错,你没听错!今天,就让我带你一起...
安卓系统说出密码,智能安全守护... 你有没有想过,你的安卓手机里藏着多少秘密?那些聊天记录、照片、文件,还有那些敏感的密码,全都在这个小...
安卓系统数控机床编程,基于安卓... 你有没有想过,那些在工厂里默默无闻的数控机床,其实也有着它们的“大脑”——那就是安卓系统数控机床编程...
华为会仍用安卓系统吗,华为将继... 你有没有想过,华为的手机会不会继续使用安卓系统呢?这个问题可是让不少手机迷们纠结不已。毕竟,华为可是...
思域如何安装安卓系统,教你如何... 车友们,你是否对车内那略显陈旧的系统感到厌倦?想要给你的爱车——本田思域,来一次科技大变身?别急,今...
win安卓双系统安装教程,轻松... 亲爱的手机控们,你是否曾梦想过拥有一部既能运行安卓系统,又能畅玩Windows应用的手机呢?现在,这...
最老版本的安卓系统,最老版本安... 你有没有想过,手机里的安卓系统其实也有它的“老古董”呢?没错,今天就要带你穿越回那个充满回忆的年代,...
安卓机子开机进不去系统,故障排... 手机突然开不了机,这可怎么办呢?是不是你也遇到了安卓机子开机进不去系统的问题?别急,今天就来给你详细...
安卓平板系统修改定制,安卓平板... 你有没有想过,你的安卓平板系统其实可以变得超级个性化呢?没错,就是那种别人一看就知道是你专属的感觉!...
QNX与安卓系统对比,性能与生... 你有没有想过,为什么有些智能手机运行得那么流畅,而有些却时不时卡顿呢?这背后,其实隐藏着两大操作系统...
超市收银系统安卓机,引领智慧购... 你有没有想过,每次去超市结账时,那台小小的收银机竟然隐藏着如此多的科技奥秘?今天,就让我带你一探究竟...
安卓suunto系统不稳定,安... 最近是不是发现你的安卓手机上安装的那个Suunto系统有点儿闹腾啊?别急,让我来给你好好捋一捋这个让...
安卓5.0系统卡刷包 你有没有遇到过安卓手机卡顿的问题?是不是觉得手机越来越慢,连打开个应用都像蜗牛爬?别急,今天就来给你...
安卓系统微信相册在哪,微信相册... 你是不是在手机上翻来覆去,就是找不到微信相册在哪里呢?别急,让我来给你详细地指一指,让你轻松找到那个...