高并发系统一定要考虑的 Bloom Filter 布隆过滤器

简介:

开篇思考

  1. 你能想到哪些方式判断一个元素是否存在集合中?
  2. 布隆过滤器并不存储数据本身,那么是怎么做到过滤的?
  3. 布隆过滤器实现?参数配置?

一般我们用来判断一个元素是否存在,会想到用 List,Map,Set 等,会将元素先保存下来,然后进行筛选。
但是这样的形式都有一个弊端就是一定要保存数据才行,可是我们仅仅想知道是否存在数据,并不要求获取实际数据,
这时候就会觉得这种方式实在是浪费空间。

什么情况下我们只需要判断是否存在这个元素呢?
在系统设计的时候,我们会考虑大量并发的形式,但是很多请求可能是在访问不存在的数据,
那么我们就没有必要继续这个请求,可以在 API 网关层就直接过滤掉。

Bloom Filter 布隆过滤器原理

Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,
被用来检测一个元素是不是集合中的一个成员。

布隆过滤器实现是不保存数据本身,而是通过 K 个 hash 函数来计算在 byte[] 数组中的存放位置,
并把这个位置的值设置为 1, 而这个 K 到底是多少个呢,要根据公式来算出,待会列出。
除了这个 K 值,我们还要计算 byte[] 数组的长度 m ,下面一并列出计算公式:

m 值计算

  • fpp : 误判率参数,(must be 0 < fpp < 1)
  • n :预估的需要过滤的总数量
  • ln :求对数,不会的把高中老师的名字写下来

K 值计算

  • m :数组长度
  • n :预估的需要过滤的总数量

下面我们以数字 11 为例来使用,有个网站可以测试布隆过滤器,
在线测试布隆

11 过滤

布隆过滤器的优点、缺点

优点:

  • 节省空间,不用保存所有数据,知识通过 hash 值来计算位置,并通过 byte[] 记录下来。
  • 速度快,时间复杂度低 O(1);

缺点:

  • 精度低,假设:a 计算的位置 1 ,3 ;b 计算的位置 5,7;c 计算的位置 1,7,那么 c 一定存在吗?
  • 不能直接删除,因为想要删除就要把对应的位置置为 0 ,如果这样做,可能会影响其他值的过滤。

11 过滤

# 布隆过滤器实现

这个其实在 google guava 包中有现成的实现,不用我们自己去实现。我们看看是怎么实现的;

   /**
   * 计算 bit 数组的长度公式
   * n : 预估数据量
   * p : 误差率 0-1
   */
   @VisibleForTesting
   static long optimalNumOfBits(long n, double p) {
       if (p == 0.0D) {
           p = 4.9E-324D;
       }

       return (long)((double)(-n) * Math.log(p) / (Math.log(2.0D) * Math.log(2.0D)));
   }
    /**
    * 计算 hash 函数个数的方法
    * n : 预估数据量
    * m : bit 数组长度
    */
    @VisibleForTesting
    static int optimalNumOfHashFunctions(long n, long m) {
        return Math.max(1, (int)Math.round((double)(m / n) * Math.log(2.0D)));
    }

动手玩一玩

  • expectedInsertions 代表预估数量,越大越准确,在下面的例子中,可以自己随意设置 p 值,过小会发现后面会返回 true
  • fpp : 误差率 0-1

import com.google.common.base.Charsets;
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;

public class BloomFilterTest {

    public static void main(String[] args) {

        int expectedInsertions = 800000000;
        double fpp = 0.00001;

        BloomFilter<CharSequence> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8), expectedInsertions, fpp);
        int i = 10000;
        while (i > 1){
            bloomFilter.put("aa" + i);
            System.out.println(bloomFilter.mightContain("ab" + i));
            i--;
        }

    }
}

喜欢文章请关注我

程序领域

目录
相关文章
|
6月前
|
消息中间件 缓存 NoSQL
谈谈高并发系统的设计方法论
设计 `高并发` 系统,就是要让该系统保证它 `整体可用` 的同时,能够尽可能多的 `处理很高的并发用户请求`,能够 `承受很大的负载流量冲击`。
726 6
|
6月前
|
缓存 NoSQL 关系型数据库
|
4月前
|
消息中间件 算法 数据库
架构设计篇问题之商城系统高并发写的问题如何解决
架构设计篇问题之商城系统高并发写的问题如何解决
|
1月前
|
Java Go 云计算
Go语言在云计算和高并发系统中的卓越表现
【10月更文挑战第10天】Go语言在云计算和高并发系统中的卓越表现
|
3月前
|
监控 算法 Java
企业应用面临高并发等挑战,优化Java后台系统性能至关重要
随着互联网技术的发展,企业应用面临高并发等挑战,优化Java后台系统性能至关重要。本文提供三大技巧:1)优化JVM,如选用合适版本(如OpenJDK 11)、调整参数(如使用G1垃圾收集器)及监控性能;2)优化代码与算法,减少对象创建、合理使用集合及采用高效算法(如快速排序);3)数据库优化,包括索引、查询及分页策略改进,全面提升系统效能。
48 0
|
4月前
|
消息中间件 缓存 监控
如何设计一个秒杀系统,(高并发高可用分布式集群)
【7月更文挑战第4天】设计一个高并发、高可用的分布式秒杀系统是一个非常具有挑战性的任务,需要从架构、数据库、缓存、并发控制、降级限流等多个维度进行考虑。
127 1
|
4月前
|
设计模式 存储 缓存
Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
54 0
|
6月前
|
算法
【数据结构与算法 11,高并发系统基础篇
【数据结构与算法 11,高并发系统基础篇
|
6月前
|
缓存 负载均衡 网络协议
作者推荐 | 高并发挑战?试试这些架构优化篇技巧,让你的系统焕发新生!
作者推荐 | 高并发挑战?试试这些架构优化篇技巧,让你的系统焕发新生!
326 1
|
6月前
|
监控 NoSQL Java
记一次线上商城系统高并发的优化
记一次线上商城系统高并发的优化
149 0

热门文章

最新文章

  • 1
    高并发场景下,到底先更新缓存还是先更新数据库?
    64
  • 2
    Java面试题:解释Java NIO与BIO的区别,以及NIO的优势和应用场景。如何在高并发应用中实现NIO?
    73
  • 3
    Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
    66
  • 4
    Java面试题:如何实现一个线程安全的单例模式,并确保其在高并发环境下的内存管理效率?如何使用CyclicBarrier来实现一个多阶段的数据处理任务,确保所有阶段的数据一致性?
    62
  • 5
    Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
    54
  • 6
    Java面试题:假设你正在开发一个Java后端服务,该服务需要处理高并发的用户请求,并且对内存使用效率有严格的要求,在多线程环境下,如何确保共享资源的线程安全?
    69
  • 7
    在Java中实现高并发的数据访问控制
    41
  • 8
    使用Java构建一个高并发的网络服务
    28
  • 9
    微服务06----Eureka注册中心,微服务的两大服务,订单服务和用户服务,订单服务需要远程调用我们的用,户服务,消费者,如果环境改变,硬编码问题就会随之产生,为了应对高并发,我们可能会部署成一个集
    37
  • 10
    如何设计一个秒杀系统,(高并发高可用分布式集群)
    127