RabbitMQ3.13.x之十_流过滤的内部结构设计与实现

RabbitMQ3.13.x之十_流过滤的内部结构设计与实现

文章目录

  • RabbitMQ3.13.x之十_流过滤的内部结构设计与实现
  • 1. 概念
    • 1. 消息发布
    • 2. 消息消费
  • 2. 流的结构
    • 1. 在代理端进行过滤
    • 2. 客户端筛选
    • 3. JavaAPI示例
    • 4. 流过滤配置
    • 5. AMQP上的流过滤
    • 6. 总结
  • 3. 相关链接

1. 概念

流过滤的思想是在代理端提供第一级的高效过滤,而无需代理解释消息。 这样,只需要流子集的使用者就不需要自己获取所有数据并处理所有过滤。 这可以大大减少传输给消费者的数据。

通过筛选,可以将筛选器值与每条消息相关联。 它可以是地理信息,例如每条消息来自的世界区域,如下图所示:

在这里插入图片描述

因此,我们的流有 1 条(绿色)消息、1 条(深蓝色)消息、2 条(紫色)消息,然后是 2 条消息。AMER``APAC``EMEA``AMER

1. 消息发布

发布者可以将每封出站邮件与其筛选器值相关联:

在这里插入图片描述

在上图中,发布者发布了 1 条(绿色)消息和 2 条(紫色)消息,这些消息将添加到流中。AMER``EMEA

2. 消息消费

当使用者订阅时,它可以指定一个或多个过滤器值,并且代理应仅发送具有此或这些过滤器值的消息。 我们很快就会看到这在实践中有点不同,但这足以理解这些概念。

在下图中,顶部的使用者指定它只想要(绿色)消息,而代理只发送这些消息。 中间的消费者和底部的消费者也是如此。AMER``EMEA``APAC

在这里插入图片描述

概念就到这里了,现在让我们来了解一下实现细节。

2. 流的结构

我们需要知道流是如何构建的,以便了解流过滤的内部结构。 流是包含段文件的目录。 每个区段文件都有一个关联的索引文件(用于了解在区段文件中给定偏移量处附加使用者的位置等)。 拥有多个“小”段文件比为整个流拥有一个大的整体文件要好:例如,删除“旧”段文件以截断流比删除大文件的开头更有效、更安全。

区段文件由包含消息的块组成。 区块中的消息数取决于入口速率(高入口速率表示一个块中的消息较多,低入口速率表示块中的消息较少)。 块中的消息数量从几条(甚至 1 条)到几千条不等。

块是怎么回事? 块是流中的工作单元:它们用于复制,更重要的是,对于我们的主题,用于消费者交付。 代理使用 sendfile 系统调用(将整个块从文件系统发送到网络套接字,而不将数据复制到用户空间)向使用者发送块,一次一个。

下图说明了流的结构:

在这里插入图片描述

有了这个,让我们看看代理如何知道是否要调度一个区块。

1. 在代理端进行过滤

想象一下,我们有一个只想要(绿色)消息的消费者。 当代理要调度一个区块时,它需要知道该区块是否包含消息。 如果是这样,它可以将块发送给消费者,如果没有,代理可以跳过该块,转到下一个块,然后重新迭代。AMER``AMER

每个区块都有一个标头,该标头可以包含一个 Bloom 过滤器,该标头告诉代理该块是否包含具有给定过滤器值的消息。 Bloom 过滤器是一种节省空间的概率数据结构,用于测试元素是否是集合的成员。 在我们的示例中,集合包含 、 和 ,元素是 。AMER``EMEA``APAC``AMER

下图说明了 3 个块的代理端过滤过程:

在这里插入图片描述

如上图所示,筛选器可能会返回误报,即不包含具有预期筛选器值的消息的块。 这是正常的,因为 Bloom 过滤器是概率性的。 不过,它们不会返回假阴性:如果过滤器显示没有(绿色)消息,我们可以确定它是真的。 我们必须忍受这种不确定性:有时我们可能会无缘无故地调度一些块,但这总比调度所有块要好。AMER

可以肯定的是,消费者可以接收到它不想要的消息:看看我们左边的第一个块,它包含消费者要求的(绿色)消息,但也包含(紫色)和(深蓝色)消息。 这就是为什么客户端也必须进行过滤的原因。AMER``EMEA``APAC

2. 客户端筛选

代理在传递消息时处理第一级过滤,但由于传递单位是块,因此使用者仍然可以接收它不想要的消息。 因此,客户端还必须执行一些筛选,这显然必须与订阅时设置的筛选值一致。

下图说明了一个消费者,它只需要(绿色)消息,并且必须执行最后一步的筛选:AMER

在这里插入图片描述

让我们看看这如何转化为应用程序代码。

3. JavaAPI示例

筛选不是侵入性的,可以作为跨领域问题进行处理,从而最大限度地减少对应用程序代码的影响。 以下是在使用流 Java 客户端(方法)声明生产者时设置从消息中提取过滤器值的逻辑:filterValue(Function<Message,String>)

Producer producer = environment.producerBuilder()
  .stream("invoices")
  .filterValue(msg -> msg.getApplicationProperties().get("region").toString())  
  .build();

在消费端,流 Java 客户端提供了设置过滤器值的方法和设置客户端过滤逻辑的方法。 声明使用者时,必须调用这两种方法:filter().values(String... filterValues)``filter().postFilter(Predicate<Message> filter)

Consumer consumer = environment.consumerBuilder()
  .stream("invoices")
  .filter()
    .values("AMER")  
    .postFilter(msg -> "AMER".equals(msg.getApplicationProperties().get("region")))  
  .builder()
  .messageHandler((ctx, msg) -> {
    // message processing code
  })
  .build();

如您所见,筛选不会更改发布和使用代码,而只是更改生产者和使用者的声明。

现在让我们看看如何以最合适的方式为用例配置流过滤。

4. 流过滤配置

关于流过滤的第一篇文章提供了一些数字(与不过滤相比,过滤节省了大约 80% 的带宽)。 流过滤的好处很大程度上取决于用例:入口速率、基数和过滤器值的分布,以及过滤器大小。 过滤器越大越好(错误率越小)。 可以为块中使用的筛选器大小设置一个介于 16 到 255 字节之间的值,默认值为 16 字节。

流 Java 客户端提供了在创建流时设置过滤器大小的方法(它在内部设置参数):filterSize(int)``stream-filter-size-bytes

environment.streamCreator()
  .stream("invoices")
  .filterSize(32)
  .create()

如何估算过滤器的尺寸? 网上有许多 Bloom 滤镜计算器。 参数包括哈希函数的数量(RabbitMQ 流过滤为 2 个)、预期元素的数量、错误率和大小。 您通常对元素的数量有所了解,因此您需要在错误率和过滤器大小之间找到权衡。

以下是一些示例:

  • 10 个值,16 个字节 => 2 % 错误率
  • 30 个值,16 个字节 => 14 % 错误率
  • 200 个值,128 个字节 => 10 % 的错误率

那么,过滤器越大越好? 不完全是:尽管 Bloom 过滤器在存储方面非常有效,因为它不存储元素,只是元素是否在集合中,过滤器大小是预先分配的。 如果将筛选器大小设置为 255,并且每个块至少包含一条具有筛选器值的消息,则每个块标头中将分配 255 个字节。 如果块包含许多大消息,这很好,因为与块大小相比,筛选器大小可以忽略不计。 但是,对于退化的情况,例如具有 10 字节消息和 10 字节筛选器值的单消息块,您最终会得到一个比实际数据更大的筛选器。

您必须尝试自己的用例,以估计过滤器大小对流大小的影响。 关于流过滤的第一篇文章提供了一个使用 Stream PerfTest 估计流大小的技巧(在不过滤的情况下读取整个流并查阅指标)。rabbitmq_stream_read_bytes_total

5. AMQP上的流过滤

尽管访问流的首选方式是流协议,但支持其他协议,例如 AMQP。 任何 AMQP 客户端库也支持流筛选:

  • 声明:将参数设置为 并使用 在声明流时设置筛选器大小。x-queue-type``stream``x-stream-filter-size-bytes
  • 发布:使用标头设置出站邮件的筛选器值。x-stream-filter-value
  • 使用:使用 consumer 参数设置预期的筛选器值(字符串或字符串数组),并使用 consumer 参数(可选)接收没有任何筛选值的消息(默认值为 )。客户端过滤仍然是必要的!x-stream-filter``x-stream-match-unfiltered``false

6. 总结

流过滤易于使用并从中受益,但有关内部的一些知识可用于优化其使用,尤其是对于棘手的用例。 请记住,客户端筛选是必需的,并且必须与配置的筛选器值一致。 这通常很容易实现。 还可以为给定的用例以最合适的方式设置过滤器大小。

3. 相关链接

参考:

Stream Filtering Internals | RabbitMQ

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/520074.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大算力芯片,正在拥抱Chiplet

随着摩尔定律走到极限&#xff0c;Chiplet被行业普遍认为是未来5年算力的主要提升技术。 在和业内人士交流时&#xff0c;有人曾表示&#xff1a;“要么业界采用Chiplet技术&#xff0c;维持摩尔定律的影响继续前进&#xff0c;要么就面临商业市场的损失。” 随着摩尔定律走到…

使用ADS确定元器件的等效感值与等效容值

使用ADS确定元器件的等效感值与等效容值 使用Win家的ADS的PDK&#xff0c;里面有一些微带电感结构&#xff0c;但是居然没有标注感值&#xff0c;给设计带来了一定的不便。 那么对于一个电路结构&#xff0c;如微带线、微带螺旋电感&#xff0c;我们如何知道其实际的感值、容…

磁盘压力测试工具(vdbenchfio)

磁盘压力测试工具&#xff08;vdbench&fio&#xff09; 最近有遇到对象挂载为文件系统的需求&#xff0c;为了测试挂载后的读写性能&#xff0c;有了解了一些测试工具。下面给大家分享下我使用的工具vdbench和fio。 1 vdbench 官网文档&#xff1a;https://www.oracle.com/…

【三十五】【算法分析与设计】综合练习(2),22。 括号生成,77。 组合,494。 目标和,模拟树递归,临时变量自动维护树定义,递归回溯,非树结构模拟树

22. 括号生成 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;["&#xff08;&#xff08;&#xff08;&#xff09;&#xff09;&#xff0…

软件杯 深度学习二维码识别

文章目录 0 前言2 二维码基础概念2.1 二维码介绍2.2 QRCode2.3 QRCode 特点 3 机器视觉二维码识别技术3.1 二维码的识别流程3.2 二维码定位3.3 常用的扫描方法 4 深度学习二维码识别4.1 部分关键代码 5 测试结果6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天…

电商数据API接口|主流电商平台数据采集的主要方式:电商API接口接入实现大量级数据采集

item_get-获得淘宝商品详情 API测试注册KEY taobao.item_get 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_search,it…

机器学习模型——K—Means算法

目录 无监督学习概念&#xff1a; 有监督学习与无监督学习&#xff1a; 无监督学习 - 聚类分析 &#xff1a; 聚类算法应用场景&#xff1a; 常用聚类算法介绍&#xff1a; 对不同的聚类算法应用选择原则&#xff1a; 基于原型聚类&#xff1a; K-Means聚类算法概念及步…

通过电机转速计算主轴旋转单圈所需时间(CODESYS ST代码)

1、伺服丝杠系统常用算法功能块 伺服丝杠系统常用算法功能块-CSDN博客文章浏览阅读353次。这篇博客主要介绍伺服、丝杠系统常用的运算功能块,其它相关运算可以查看下面文章链接:信捷PLC脉冲频率、位移、转速相关计算(C语言编程应用)_RXXW_Dor的博客-CSDN博客。https://rxxw-…

UE4_如果快速做出毛玻璃效果_假景深

UE4_如果快速做出毛玻璃效果_假景深 2022-08-20 15:02 一个SpiralBlur-SceneTexture材质节点完成效果&#xff0c;启用半透明材质通过修改BlurAmount数值大小调整效果spiralBlur-SceneTexture custom节点&#xff0c;HLSL语言float3 CurColor 0;float2 BaseUV MaterialFloa…

系统思考—领导者

“组织是船&#xff0c;领导者是什么角色&#xff1f;” 对于这个看似简单的问题&#xff0c;很多人可能会直观地想到船长或舵手。但学习型组织的倡导者彼得圣吉给出了另一种视角&#xff1a;如果组织是一艘船&#xff0c;那么领导者首先应该是这艘船的设计师。 在我近期与各个…

Linux:进程等待究竟是什么?如何解决子进程僵尸所带来的内存泄漏问题?

Linux&#xff1a;进程等待究竟是什么&#xff1f;如何解决子进程僵尸所带来的内存泄漏问题&#xff1f; 一、进程等待的概念二、进程等待存在的意义三、如何进行进程等待3.1 wait()是实现进程等待1、wait()原型2. 验证wait()能回收僵尸子进程的空间 3.2 waitpid()实现进程等待…

电子积木方案开发商

东莞市酷得智能科技有限公司电子积木方案开发商 提供消费电子解决方案、提供IC技术支持&#xff0c;全国线上线下服务 积木小车底层驱动开发过程主要涉及到以下几个方面&#xff1a; 首先&#xff0c;需要对小车底盘结构、硬件、模块等有深入的了解。底盘承载着机器人定位、导…

Kubernetes(k8s):Pod 的 Node Selector详解

Kubernetes&#xff08;k8s&#xff09;&#xff1a;Pod 的 Node Selector详解 1、什么是Node Selector&#xff1f;2、Node Selector的工作原理3、Node Selector的用法1、例如&#xff1a;给node01 、node02 分别打上标签2、使用标签调度Pod3、删除节点的标签 &#x1f496;Th…

java面试题(Redis)

事情干的差不多了&#xff0c;开刷面试题和算法&#xff0c;争取在短时间内快速成长&#xff0c;理解java面试的常见题型 一、redis使用场景&#xff1a; 缓存&#xff1a;穿透、击穿、雪崩 双写一致、持久化 数据过期、淘汰策略 分布式锁&#xff1a;setnx、redisson 计数…

武汉星起航推出亚马逊一站式孵化平台,助力合作伙伴快速成长

武汉星起航电子商务有限公司&#xff0c;自2020年正式成立以来&#xff0c;凭借其专业的运营团队和丰富的行业经验&#xff0c;在跨境电商领域取得了显著的成绩。为了进一步满足市场需求&#xff0c;武汉星起航决定推出亚马逊一站式孵化平台&#xff0c;旨在为合作伙伴提供更全…

网盘分享链接

点击打开下面这条链接&#xff0c;保存文件 https://pan.xunlei.com/s/VNuDMRtfBQvmfqqwjsBAIg2pA1?pwdhqd3 网盘里文件太多&#xff0c;找不到&#xff0c;怎么办&#xff1f; 进入我的B站主页【I泠霖I的个人空间-哔哩哔哩】 https://b23.tv/VYxaiJb&#xff0c;点击右上角的…

PC发送指令给单片机控制LED(与上一篇文章相反)

此时要重新配置寄存器 &#xff0c;实现电脑往单片机传输数据 1、配置SCON寄存器的REN 即 REN 1 2、有TI&#xff08;发送中断&#xff09;就有RI&#xff08;接收中断&#xff09; 3、优化 发现发送 o 时&#xff0c;D5亮灯会有延迟 下面就是做到真正的无延迟的全双工通信 …

JVM基础

初识JAM JVM就是JAVA虚拟机&#xff0c;本质上是一个运行在计算机上的程序&#xff0c;他的职责是运行JAVA字节码文件. 下面是java代码执行过程 JVM的功能 1.解释和运行 对字节码文件中的指令实时的解释成机器码 2.内存管理 自动为对象&#xff0c;方法等分配内存自动的垃圾回…

27.WEB渗透测试-数据传输与加解密(上)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;26.WEB渗透测试-BurpSuite&#xff08;五&#xff09; BP抓包网站网址&#xff1a;http:…

IIC协议——OLED(128*64)外设

IIC协议&#xff08;Inter-Integrated Circuit Protocol&#xff09;&#xff0c;也被称为I2C&#xff08;Inter-Integrated Circuit&#xff09;&#xff0c;是一种串行通信协议&#xff0c;通常用于连接集成电路&#xff08;IC&#xff09;和外部设备&#xff0c;例如传感器、…