12-布隆过滤器+布谷鸟过滤器+分布式锁

布隆过过滤器

用于解决 缓存穿透问题

image-20220427165617223

布隆过滤器 本质就是二进制 01组成的二进制数组,工作原理也很简单 就是判断用户访问的数据是否存在于缓存中,

布隆过滤器工作原理

前置知识 哈希函数:

通过同一个哈希函数 得到的哈希值不相同 那么两个哈希值原始输入的值肯定是不同的。

通过同一个哈希函数,得到的哈希值相同, 两个哈希值的原始值有可能相同 有可能不同。

总结下来也就是 哈希值不同 原来的值肯定不同 哈希值相同 原来的值有可能相同 有可能不同。

布隆过滤器为什么要哈希函数存储那?

哈希函数最后存入到布隆过滤器中就是 0和1 存在数组就是1 不存在就是0 这比存原始数据大大减少了内存的占用

  1. 数据插入过程

数据存入过程

image-20220427171726085

以上图为例

原始数据hello 经过两个hash函数 计算出两个位置 3 和5

在二进制数组中就把 3和5的位置改为1 其它为0

000101000 就是hello在布隆过滤器中的位置

读取过程与存入过程相似,通过hash计算读取值的hash函数 判断是否存在 存在就去缓存中读取数据

删除操作很难操作

image-20220426155603558

一个下标存了两个数据 没法删除 哈希值相同

布隆过滤器的优缺

优点

  1. 插入查询速度非常快

  2. 查询快 只需要判断0 1

  3. 安全性好 过滤器中没有存在原始数据 即使泄露了 一堆0 1 也不代表任何内容

    缺点

  4. 存在误判 这和使用了hash函数有关 请看下图

    image-20220427172633211

    hash函数 如果两个hash的值相同 那么两个值可能相同 也可能不相同, 那么就存在上图的情况,两个完全不同的值hash函数相同 如果我们存入的是hello 用户查询java 而我们的缓存中没有java 但是布隆过滤器反馈的结果是java存在 这样过滤器就失效了

  5. 无法删除元素 也是由于上面hash函数的原因 同一个或多个hash函数的值 可以存多个原始的值 像上面 000101000 既存了hello的 也存了 java 那么就无法进行删除操作

如何解决布隆过滤器的缺点那?

有一个办法 一个是增加 hash函数的个数

image-20220427173417432

每个原始数据 在数组中由多个hash函数值表示 ,值越多 和其它值撞车的概率越小

布隆过滤器在使用的时候 有一个设置的值是误判率

误判率设置的越小 需要判断的哈希函数越多 占用的空间越大 执行的越慢,效率越差

当我们通过程序调用布隆过滤器的时候 可以设置误判率 误判率越高 则需要更大的空间和更多的哈希函数

所以误判率的要求 根据现实业务的需要 需要在性能和准确率上做一个均衡的选择

布谷鸟过滤器

布谷鸟过滤器的原理

布谷鸟过滤器的原则就是鸠占鹊巢

鸠 就是布谷鸟 自己从来不搭窝,下蛋产子的时候占用其它鸟的窝,其他鸟类帮它一起孵化 布谷鸟体型比较大 把其它小鸟挤走

布谷鸟哈希

布谷鸟哈希 会把个原始数据经过哈希计算出两个位置,如果两个位置是空的 就直接放到一个位置 ,有一个位置被占用了就去另外一个位置,如果两个位置都占满了,就把原来的数据踢走, 自己霸占位置 同时为踢走的数据再选一个位置,因为每一个数据都有两个位置

经过布谷鸟哈希计算的值叫指纹数据 ,代表原始数据

布谷鸟过滤器的问题

挤兑循环问题 当数据太大太拥挤的时候 新的数据进来 就要把原来的数据踢走,而被踢走的数据寻找位置又要提走其它数据的位置,这样一直循环就形成了挤兑循环的问题

解决循环挤兑问题有两种方法

第一增加hash函数个数 一个值有3个hash值 也就有3个位置 存入值只占用1个位置 空余三个位置 。

image-20220427180142242

第二种 一个位置 把这个位置做成数组 分成四小份 每一份放一个数据 相当于二维数组,数组内嵌套数组

同时四小分都是连续的 查询性能高 数组套娃 二维数组

image-20220427180540295

布谷鸟过滤器的删除的问题

通常布谷鸟过滤器在资料里会显示 它实现了布隆过滤器不可以删除数据的功能,那在生产环境是否可以使用那

布谷鸟过滤器官方建议存入的数据不能超过kb+1 不能大于9

k=hash个数 b=座位个数,如果一个原始数据 有两个哈希函数 一个位置分为4个座位 2*4+1=9 存入相同的数据不能大于9

image-20220426175512038

image-20220426175520635

我们以两个哈希函数 1个哈希函数4个位置计算

举例如果连续存储相同的数据8次 八个位置都会占满 存入第九个数的时候 插入不进去了,因为存入第九个数据 前面八个算一个大的索引 后面你存到哪里 都会和这个索引冲突

同时会出现八个数据 指纹相同 位置相同 会造成误查询 和误删除。

如果需要删除一个数据 一个指纹数据是 1个字节 =256中可能,我们还需要单独计算每个数据的插入次数 ,所以布谷鸟实现的数据删除很鸡肋 不可能实现,删除之前的筛查就很费劲。

分布式锁

posted @ 2022-06-09 16:00  机猿巧合  阅读(413)  评论(0编辑  收藏  举报