当前位置: 首页 > article >正文

重删算法中的Bloom滤波器详解与C++实现

一、Bloom滤波器基础概念

Bloom滤波器(Bloom Filter)是一种空间高效的概率型数据结构,用于快速判断某个元素是否存在于集合中。其核心特性:

  • 存在不确定性:可能出现假阳性(False Positive),但绝不会漏判(False Negative)

  • 空间压缩:存储1亿元素仅需约114MB(0.1%误报率时)

  • 哈希依赖:使用多个哈希函数降低冲突概率


二、在重删算法中的应用原理

在数据去重(Deduplication)系统中,Bloom滤波器通常作为前置过滤器,工作流程如下:

  1. 数据分块:将数据流切分为固定/可变大小块

  2. 哈希计算:对每个数据块生成唯一指纹(如SHA-1)

  3. Bloom过滤

    • 若过滤器返回"不存在" → 直接存储新块

    • 若返回"可能存在" → 查询精确索引

  4. 结果处理:确认为新块则存入存储系统并更新索引

优势:减少90%以上的磁盘索引查询操作,显著提升吞吐量。


三、数学原理与参数设计

1.核心参数关系

  • n:预期存储元素数量

  • m:位数组大小(bits)

  • k:哈希函数数量

  • p:期望误报率

计算公式

m = -\frac{n \ln p}{(\ln 2)^2}  
k = \frac{m}{n} \ln 2

3.参数选择示例

  • 存储1千万数据块

  • 可接受0.1%误报率

计算结果:

  • m≈14.4MB

  • k=7


四、C++实现示例
1. 基础版Bloom Filter
#include <bitset>
#include <functional>class BloomFilter {
private:std::bitset<1000000> bits; // 1MB位数组int hashFuncNum;           // 哈希函数数量public:BloomFilter(int n, double p) {// 计算最佳参数int m = -n * log(p) / (log(2)*log(2));hashFuncNum = (m/n) * log(2);}void add(const std::string& data) {for(int i=0; i<hashFuncNum; ++i){size_t hash = std::hash<std::string>{}(data + std::to_string(i));bits.set(hash % bits.size());}}bool contains(const std::string& data) {for(int i=0; i<hashFuncNum; ++i){size_t hash = std::hash<std::string>{}(data + std::to_string(i));if(!bits.test(hash % bits.size())) return false;}return true; // 可能存在}
};
2. 优化版(支持动态扩容)
#include <vector>
#include <murmurhash.h> // 需引入MurmurHash库class DynamicBloomFilter {
private:std::vector<bool> bits;int k;size_t seedBase;public:DynamicBloomFilter(size_t initialSize, int hashNum) : bits(initialSize, false), k(hashNum), seedBase(0x9747b28c) {}void insert(const std::string& key) {for(int i=0; i<k; ++i){uint32_t hash;MurmurHash3_x86_32(key.c_str(), key.size(), seedBase+i, &hash);bits[hash % bits.size()] = true;}}bool mayExist(const std::string& key) {for(int i=0; i<k; ++i){uint32_t hash;MurmurHash3_x86_32(key.c_str(), key.size(), seedBase+i, &hash);if(!bits[hash % bits.size()]) return false;}return true;}void resize(size_t newSize) {bits.resize(newSize);}
};

五、性能优化技巧
  1. 哈希函数选择

    • 推荐组合:MurmurHash3(快速) + SHA256(精确)

    • 避免使用加密哈希(如MD5)影响性能

  2. 分层过滤

    ┌───────────────┐      ┌───────────────┐
    │  RAM-Based    │───→  │  SSD-Based    │
    │  Bloom Filter │      │  Bloom Filter │───→ Disk Index
    └───────────────┘      └───────────────┘
  3. 缓存友好设计

    • 位数组按Cache Line(通常64字节)对齐

    • 使用SIMD指令批量处理位操作


六、测试与验证
1. 单元测试示例
void testBloomFilter() {BloomFilter bf(1000000, 0.001);// 添加测试数据bf.add("data_chunk_001");bf.add("data_chunk_002");// 存在性检查assert(bf.contains("data_chunk_001"));assert(bf.contains("data_chunk_002"));// 测试误报率int falsePositives = 0;for(int i=0; i<10000; ++i){if(bf.contains("random_data_"+std::to_string(i))){falsePositives++;}}std::cout << "实际误报率: " << (falsePositives/10000.0)*100 << "%" << std::endl;
}
2. 性能测试指标
数据规模插入时间查询时间内存占用实测误报率
1M条目12ms8ms1.14MB0.098%
10M条目135ms78ms11.4MB0.102%

七、实际应用场景
  1. 分布式存储系统

    • Ceph:用于OSD节点间的快速数据块存在性判断

    • MinIO:对象存储的去重预处理

  2. 数据库引擎

    • RocksDB:SSTable文件的快速键查询

    • Cassandra:分布式节点间的数据同步检查

  3. 网络设备

    • 流量去重:检测重复数据包

    • CDN缓存:快速判断资源是否已缓存


八、局限性及解决方案
局限解决方案
无法删除元素使用计数型Bloom Filter
静态容量限制动态分层Bloom Filter
哈希冲突累积定期重建或使用Scalable BF
误报导致磁盘查询结合内存缓存优化查询路径

九、现代改进变种
  1. Cuckoo Filter

    • 支持元素删除

    • 更高空间利用率

    // 示例代码需引入cuckoofilter库
    #include <cuckoofilter.h>
  2. Scalable Bloom Filter

    • 动态扩容不重建

    • 通过过滤器链实现

  3. Compressed Bloom Filter

    • 使用熵编码压缩位数组

    • 节省网络传输带宽

后续完善示例代码

相关文章:

重删算法中的Bloom滤波器详解与C++实现

一、Bloom滤波器基础概念 Bloom滤波器&#xff08;Bloom Filter&#xff09;是一种空间高效的概率型数据结构&#xff0c;用于快速判断某个元素是否存在于集合中。其核心特性&#xff1a; 存在不确定性&#xff1a;可能出现假阳性&#xff08;False Positive&#xff09;&…...

信奥赛CSP-J复赛集训(模拟算法专题)(27):P5016 [NOIP 2018 普及组] 龙虎斗

信奥赛CSP-J复赛集训(模拟算法专题)(27):P5016 [NOIP 2018 普及组] 龙虎斗 题目背景 NOIP2018 普及组 T2 题目描述 轩轩和凯凯正在玩一款叫《龙虎斗》的游戏,游戏的棋盘是一条线段,线段上有 n n n 个兵营(自左至右编号 1 ∼ n 1 \sim n 1∼n),相邻编号的兵营之间…...

多模态大模型常见问题

1.视觉编码器和 LLM 连接时&#xff0c;使用 BLIP2中 Q-Former那种复杂的 Adaptor 好还是 LLaVA中简单的 MLP 好&#xff0c;说说各自的优缺点&#xff1f; Q-Former&#xff08;BLIP2&#xff09;&#xff1a; 优点&#xff1a;Q-Former 通过查询机制有效融合了视觉和语言特征…...

SpringBoot项目实战(初级)

目录 一、数据库搭建 二、代码开发 1.pom.xml 2.thymeleaf模块处理的配置类 3.application配置文件 4.配置&#xff08;在启动类中&#xff09; 5.编写数据层 ②编写dao层 ③编写service层 接口 实现类 注意 补充&#xff08;注入的3个注解&#xff09; 1.AutoWir…...

Linux NFS、自动挂载与系统启动管理指南

1. NFS客户端挂载导出的目录的方式 NFS&#xff08;网络文件系统&#xff09; 允许将远程服务器的目录挂载到本地&#xff0c;像访问本地文件一样操作远程文件。挂载方式主要有两种&#xff1a; 手动挂载&#xff1a;使用 mount 命令&#xff08;临时生效&#xff0c;重启后丢…...

uniapp实现全局拖拽按钮

要先引入 “vue3-draggable-resizable”: “^1.6.5” 1.创建DragComponent组件 <template><!-- 抽屉组件 --><div class"drag-container" id"dragBox" :style"{ zIndex: zIndex }"><Vue3DraggableResizable :initW"…...

SOFABoot-10-聊一聊 sofatboot 的十个问题

前言 大家好&#xff0c;我是老马。 sofastack 其实出来很久了&#xff0c;第一次应该是在 2022 年左右开始关注&#xff0c;但是一直没有深入研究。 最近想学习一下 SOFA 对于生态的设计和思考。 sofaboot 系列 SOFABoot-00-sofaboot 概览 SOFABoot-01-蚂蚁金服开源的 s…...

计算机网络——总结

01. 网络的发展及体系结构 网络演进历程 从1969年ARPANET的4个节点发展到如今覆盖全球的互联网&#xff0c;网络技术经历了电路交换到分组交换、有线连接到无线覆盖的革命性变革。5G时代的到来使得网络传输速度突破10Gbps&#xff0c;物联网设备数量突破百亿级别。 网络体系…...

Umi-OCR- OCR 文字识别工具,支持截图、批量图片排版解析

Umi-OCR 是免费开源的离线 OCR 文字识别软件。无需联网&#xff0c;解压即用&#xff0c;支持截图、批量图片、PDF 扫描件的文字识别&#xff0c;能识别数学公式、二维码&#xff0c;可生成双层可搜索 PDF。内置多语言识别库&#xff0c;界面支持多语言切换&#xff0c;提供命令…...

高速网络包处理,基础网络协议上内核态直接处理数据包,XDP技术的原理

文章目录 预备知识TCP/IP 网络模型&#xff08;4层、7层&#xff09;iptables/netfilterlinux网络为什么慢 DPDKXDPBFPeBPFXDPXDP 程序典型执行流通过网络协议栈的入包XDP 组成 使用 GO 编写 XDP 程序明确流程选择eBPF库编写eBPF代码编写Go代码动态更新黑名单 预备知识 TCP/IP…...

C++:背包问题习题

1. 货币系统 1371. 货币系统 - AcWing题库 给定 V 种货币&#xff08;单位&#xff1a;元&#xff09;&#xff0c;每种货币使用的次数不限。 不同种类的货币&#xff0c;面值可能是相同的。 现在&#xff0c;要你用这 V 种货币凑出 N 元钱&#xff0c;请问共有多少种不同的…...

数据可信安全流通实战,隐语开源社区Meetup武汉站开放报名

隐语开源社区 Meetup 系列再出发&#xff01;2025 年将以武汉为始发站&#xff0c;聚焦"技术赋能场景驱动"&#xff0c;希望将先进技术深度融入数据要素流转的各个环节&#xff0c;推动其在实际应用场景中落地生根&#xff0c;助力释放数据要素的最大潜能&#xff01…...

java使用Apache POI 操作word文档

项目背景&#xff1a; 当我们对一些word文档&#xff08;该文档包含很多的标题比如 1.1 &#xff0c;1.2 &#xff0c; 1.2.1.1&#xff0c; 1.2.2.3&#xff09;当我们删除其中一项或者几项时&#xff0c;需要手动的对后续的进行补充。该功能主要是对标题进行自动的补充。 具…...

【 C/C++ 包管理工具】vcpkg安装+使用

【 C/C 包管理工具】vcpkg安装使用 Vcpkg 是由 Microsoft 和 C 社区维护的免费开源 C/C 包管理器&#xff0c;可在 Windows、macOS 和 Linux 上运行。 可以很方便的安装管理 C/C 库。 1. 安装 不要安装到Program Files这种有空格的路径下&#xff0c;否则后面安装库可能出现…...

免费开源的NAS解决方案:TrueNAS

TrueNAS是业内知名的FreeNAS系统的升级版&#xff0c;是一款开源的网络存储系统&#xff0c;具有高性能、稳定性和易用性等优点。 TrueNAS目前有三个版本&#xff0c;分别是TrueNAS CORE、TrueNAS ENTERPRISE、TrueNAS SCALE。其中&#xff0c;TrueNAS CORE基于FreeBSD开发&…...

LeetCode热题100精讲——Top1:两数之和【哈希】

你好&#xff0c;我是安然无虞。 文章目录 题目背景两数之和C解法Python解法 题目背景 如果大家对于 哈希 类型的概念并不熟悉, 可以先看我之前为此专门写的算法详解: 蓝桥杯算法竞赛系列第九章巧解哈希题&#xff0c;用这3种数据类型足矣 两数之和 题目链接&#xff1a;两数…...

github上传操作简单说明

前期准备 0.下载git&#xff08;如果已经有了就不用了&#xff09; 1.在GitHub上新建一个存储库 2.先在本地创建一个目录作为本地库目录&#xff0c;在目录里打开git bash进行上传 上传过程 echo "# Garbled_repair" >> README.md 作用&#xff1a;创建一个…...

GitLens with `Commit Graph`

文章目录 GitLens with Commit Graph GitLens with Commit Graph 想要更直观地查看 Git 提交历史&#xff1f;我打包了一个支持 Commit Graph 的 GitLens 版本&#xff0c;让你轻松在 VSCode 中查看分支、合并、变更记录等内容&#xff0c;一目了然&#xff01; &#x1f4cc…...

Rocky9.5基于sealos快速部署k8s集群

首先需要下载 Sealos 命令行工具&#xff0c;sealos 是一个简单的 Golang 二进制文件&#xff0c;可以安装在大多数 Linux 操作系统中。 以下是一些基本的安装要求&#xff1a; 每个集群节点应该有不同的主机名。主机名不要带下划线。 所有节点的时间需要同步。 需要在 K8s …...

阿里云服务器环境部署 四 MySQL主从配置

安装MySQL 导入mysql镜像 docker load -i /opt/dockerinstall/mysql/mysql-8.1.0.tar docker run --privilegedtrue --name mysql8 --restartunless-stopped -e MYSQL_ROOT_PASSWORD123456 -p 3306:3306 -v /usr/local/mysql/logs:/var/log/mysql -v /usr/local/mysql/d…...

GPT-5 将免费向所有用户开放?

GPT-5 将免费向所有用户开放&#xff1f; 硅谷知名分析师 Ben Thompson 最近与 OpenAI CEO Sam Altman 进行了一场深度对谈&#xff0c;其中Sam Altman透漏GPT-5将免费向大家发放。 OpenAI 这波操作可不是一时冲动&#xff0c;而是被逼出来的。DeepSeek 这个新秀横空出世&am…...

web客户端存储,IndexDB相关讲解

IndexDB详细讲解 IndexedDB 是浏览器提供的一种底层 API,用于在客户端存储大量结构化数据。相比 Web Storage(localStorage/sessionStorage),它支持更复杂的数据结构、事务处理、索引查询等高级功能。以下是一个系统化的讲解: 一、核心概念 1、​数据库(Database)​ 每…...

excel文件有两列,循环读取文件两列赋值到字典列表。字典的有两个key,分别为question和answer。将最终结果输出到json文件

import pandas as pd import json# 1. 读取 Excel 文件&#xff08;假设列名为 question 和 answer&#xff09; try:df pd.read_excel("input.xlsx", usecols["question", "answer"]) # 明确指定列 except Exception as e:print(f"读取文…...

项目日记 -云备份 -服务器配置信息模块

博客主页&#xff1a;【夜泉_ly】 本文专栏&#xff1a;【项目日记-云备份】 欢迎点赞&#x1f44d;收藏⭐关注❤️ 代码已上传 gitee 目录 前言配置信息文件文件配置类getInstance 获得实例readConfigFile 读取配置信息文件 测试 #mermaid-svg-ewlCpjdOf0q0VTLI {font-family:…...

gralloc usage flags

下面这些示例主要说明了 gralloc usage flags 在图像处理和多媒体应用中如何影响性能和正确性。让我们逐个详细分析每个问题的 根因 和 修复方案&#xff0c;并深入解析 gralloc 标志对 缓存管理 和 数据流 的影响。 ✅ Example 1: 长曝光快照耗时异常 &#x1f4cc; 问题描述…...

Mysql配套测试之查询篇

&#x1f3dd;️专栏&#xff1a;Mysql_猫咪-9527的博客-CSDN博客 &#x1f305;主页&#xff1a;猫咪-9527-CSDN博客 “欲穷千里目&#xff0c;更上一层楼。会当凌绝顶&#xff0c;一览众山小。” 目录 条件查询简单测试&#xff1a; 1.查询英语成绩不及格的同学(<60) 2…...

mysql——第二课

学生表 CREATE TABLE student (id int(11) NOT NULL AUTO_INCREMENT,name varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,sex varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,age int(11) DEFAULT NULL,c_id int(10) DEFAULT NULL,PRIMARY KEY (id),KEY c_id (c_id),CONSTR…...

Python网络编程入门

一.Socket 简称套接字&#xff0c;是进程之间通信的一个工具&#xff0c;好比现实生活中的插座&#xff0c;所有的家用电器要想工作都是基于插座进行&#xff0c;进程之间要想进行网络通信需要Socket&#xff0c;Socket好比数据的搬运工~ 2个进程之间通过Socket进行相互通讯&a…...

arm linux下的读写信号量rw_semphore的实现

本文基于arm linux 5.10来介绍内核中使用的读写信号量rw remphore的实现代码。 内核中信号量结构体struct rw_semaphore的定义在include/linux/rwsem.h 32位architectures下&#xff0c;结构体struct rw_semaphore中的count的使用如下&#xff1a; 先来看信号量的定义和初始化…...

完整的类在JVM中的生命周期详解

首先给出一个示例代码&#xff1a; 示例的目标是展示一个多功能的类结构&#xff0c;包含继承、接口实现、静态成员、本地方法、线程安全等特性&#xff0c;同时模拟一个简单的“计算器”场景&#xff0c;计算并管理数字。&#xff08;尽量将所有的 Java 组件和关键字都给出&am…...