环形缓冲区– Disruptor背后的数据结构

2023-11-02

环形缓冲区– Disruptor背后的数据结构

Disruptor是一个高性能的库,用于在线程之间传递消息,该库由LMAX Exchange公司在几年前开发和开源。 他们创建了此软件来处理其零售金融交易平台中的巨大流量(超过600万TPS)。 在2010年,他们通过在单个线程上执行所有业务逻辑,每个人都对他们的系统能达到如此快的速度感到惊讶。 尽管单线程是解决方案中的重要概念,但Disruptor(这不是业务逻辑的一部分)可以在多线程环境中工作。 Disruptor基于环形缓冲区,这绝对不是一个新概念。

环形缓冲区

环形缓冲区有很多名称。 您可能听说过循环缓冲区,循环队列或循环缓冲区。 他们的意思都是一样的。 它基本上是一个线性数据结构,其中端点指向结构的开头。 很容易将其视为没有结尾的圆形数组。

可以想象,环形缓冲区通常用作队列。 它具有读写位置,分别供消费者和生产者使用。 当读或写索引到达基础数组的末尾时,它将被设置回0。此活动通常称为“环绕”,并且需要更多说明。

环绕

请考虑以下情况:我们在数组的末尾具有写入索引,而在数组的开始处具有读取索引。 包裹起来安全吗?

好吧,很容易想象一个流式处理示例,因为不再需要更新的,更相关的数据,因此不再需要过时的数据,但是通常,我们关心尚未处理的数据。 如果是这种情况,则返回错误的布尔值或阻塞(如传统的有界队列一样)将起作用。 如果这些解决方案都不能令我们满意,我们可以实现一个环形缓冲区,该缓冲区可以调整自身大小(但仅在缓冲区满时才可用,而不仅仅是生产者到达数组末尾并且可以安全地环绕)。 调整大小将需要将所有元素移动到新分配的更大数组(如果将数组用作基础数据结构),这当然是昂贵的操作。

干扰器中的环形缓冲区

环形缓冲区在Disruptor中解决什么样的问题? 让我们看一下Disruptor的典型用例:

如您所见,我们将一条消息发送到多个使用者(1-4)的输入队列中-因此它是典型的多播(一种发布和订阅语义)。 然后,我们遇到了障碍–我们希望所有消费者在继续下一步之前完成对消息的处理。 传递障碍后,消息将转到最后一个使用者的输入队列。 总而言之,我们有四个在相同数据上运行的独立(因此可能并行)的任务(消费者1-4)和一个任务(从属消费者),这要求所有之前的任务都必须先完成才能开始工作。

在这种架构中,环形缓冲区在哪里? 好吧,环形缓冲区实际上就是这种架构。

假设一条消息是环形缓冲区中的单个项目。 环形缓冲区代表我们的实际队列(如果您愿意,也可以代表多个下游队列)。 每个使用者都是循环遍历环形缓冲区的单独线程(如果愿意,也可以使用队列中的消息)。

屏障的实现方式是:从属消费者无法越过需要开始处理环形缓冲区项目(消息)之前需要完成的任何消费者。

单作家原则

即使使用Disruptor的最有效方法是拥有一个生产者和多个消费者,但多生产者场景也是可能的。 在这种情况下,同一游标上可能存在写争用。 Disruptor并未使用传统的锁来解决此问题-因此它是无锁的( BlockingWaitStrategy除外)。 相反,它依赖于内存屏障和/或高性能CAS操作。

如果从属消费者需要以前的任何消费者产生的某些数据怎么办? 消费者是否还可以修改环形缓冲区中的商品并因此成为作家? 事实证明,这里使用了一个非常简单的规则-环形缓冲区中的每个项目都由一组字段组成,并且每个字段最多具有一个允许其写入的使用者。 这样可以防止使用者之间发生任何写争用。

摘要

还有许多其他因素可以使Disruptor快速运行,例如:

  • 以批处理方式使用消息
  • 使用环形缓冲区中的数据局部性,CPU缓存友好的优势
  • 在环形缓冲区中预先分配消息,以避免频繁垃圾回收项目(因此可以重复使用)

正如我在这里解释的那样,即使环形缓冲区是一个相对简单的数据结构,它也可以轻松地用于实现更复杂的场景,而Disruptor只是一个示例。

翻译自: https://www.javacodegeeks.com/2017/12/ring-buffer-data-structure-behind-disruptor.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

环形缓冲区– Disruptor背后的数据结构 的相关文章

  • 对使用 importlib.util 导入的对象进行酸洗

    我在使用Python的pickle时遇到了一个问题 我需要通过将文件路径提供给 importlib util 来加载一些 Python 模块 如下所示 import importlib util spec importlib util sp
  • 如何在 Django 中使用基于类的视图创建注册视图?

    当我开始使用 Django 时 我几乎使用 FBV 基于函数的视图 来处理所有事情 包括注册新用户 但当我更深入地研究项目时 我意识到基于类的视图通常更适合大型项目 因为它们更干净且可维护 但这并不是说 FBV 不是 无论如何 我将整个项目
  • 迭代列表的奇怪速度差异

    我创建了两个重复两个不同值的长列表 在第一个列表中 值交替出现 在第二个列表中 一个值出现在另一个值之前 a1 object object 10 6 a2 a1 2 a1 1 2 然后我迭代它们 不对它们执行任何操作 for in a1 p
  • 如何在 Azure 数据工厂 - Databricks 中使用 continuation_token 获取 ADF Pipeline 运行详细信息的下一页?

    我在用 adf client pipeline runs query by factory resourceGroupName 工厂名称 过滤器参数 的方法azure mgmt datafactory DataFactoryManageme
  • Werkzeug 中的线程和本地代理。用法

    首先 我想确保我正确理解了功能的分配 分配本地代理功能以通过线程内的模块 包 共享变量 对象 我对吗 其次 用法对我来说仍然不清楚 也许是因为我误解了作业 我用烧瓶 如果我有两个 或更多 模块 A B 我想将对象C从模块A导入到模块B 但我
  • 为什么我应该使用 WSGI?

    使用 mod python 一段时间了 我读了越来越多关于 WSGI 有多好的文章 但没有真正理解为什么 那么我为什么要切换到它呢 有什么好处 这很难吗 学习曲线值得吗 为了用 Python 开发复杂的 Web 应用程序 您可能会使用更全面
  • 在 Windows 上使用带有对数刻度的 matplotlib 时出现 Unicode 错误

    我正在使用 python 2 6 和 matplotlib 如果我运行 matplotlib 库页面中提供的示例 histogram demo py 它工作正常 我已经大大简化了这个脚本 import numpy as np import
  • 使用 NLP 进行地址分割

    我目前正在开发一个项目 该项目应识别地址的每个部分 例如来自 str Jack London 121 Corvallis ARAD ap 1603 973130 输出应如下所示 street name Jack London no 121
  • QuerySyntaxException:无法找到类

    我正在使用 hql 生成 JunctionManagementListDto 类的实际 Java 对象 但我最终在控制台上出现以下异常 org hibernate hql internal ast QuerySyntaxException
  • 返回 Java 8 中的通用函数接口

    我想写一种函数工厂 它应该是一个函数 以不同的策略作为参数调用一次 它应该返回一个函数 该函数根据参数选择其中一种策略 该参数将由谓词实现 嗯 最好看看condition3为了更好的理解 问题是 它没有编译 我认为因为编译器无法弄清楚函数式
  • Python对象初始化性能

    我只是做了一些快速的性能测试 我注意到一般情况下初始化列表比显式初始化列表慢大约四到六倍 这些可能是错误的术语 我不确定这里的行话 例如 gt gt gt import timeit gt gt gt print timeit timeit
  • Spring-ws:如何从没有“Request”元素的 xsd 创建 Wsdl

    尝试为客户端实现 SOAP Web 服务 我需要一个 wsdl 文件来通过soapUI 测试该服务 但正如您在下面看到的 这个 xsd 没有 Request 和 Response 方法 所有请求和响应都被定义为基本 ServiceProvi
  • 在 Google App-Engine JAVA 中将文本转换为字符串,反之亦然

    如何从字符串转换为文本 java lang String to com google appengine api datastore Text 反之亦然 Check Javadoc http code google com appengin
  • Android:无法发送http post

    我一直在绞尽脑汁试图弄清楚如何在 Android 中发送 post 方法 这就是我的代码的样子 public class HomeActivity extends Activity implements OnClickListener pr
  • OpenCSV:将嵌套 Bean 映射到 CSV 文件

    我正在尝试将 bean 映射到 CSV 文件 但问题是我的 bean 具有其他嵌套 bean 作为属性 所发生的情况是 OpenCSV 遍历属性找到一个 bean 然后进入其中并映射该 bean 内的所有数据 如果找到另一个 bean 它就
  • 通过 Web 界面执行 python 单元测试

    是否可以通过 Web 界面执行单元测试 如果可以 如何执行 EDIT 现在我想要结果 对于测试 我希望它们是自动化的 可能每次我对代码进行更改时 抱歉我忘了说得更清楚 EDIT 这个答案此时已经过时了 Use Jenkins https j
  • org.apache.commons.net.io.CopyStreamException:复制时捕获 IOException

    我正在尝试使用以下方法中的代码将在我的服务器中创建的一些文件复制到 FTP 但奇怪的是我随机地低于错误 我无法弄清楚发生了什么 Exception org apache commons net io CopyStreamException
  • 使用 Python 将对象列表转为 JSON

    我在转换时遇到问题Object实例到 JSON ob Object list name scaping myObj base url u number page for ob in list name json string json du
  • 使用Multiprocessing和Pool时如何访问全局变量?

    我试图避免将变量冗余地传递到dataList e g 1 globalDict 2 globalDict 3 globalDict 并在全球范围内使用它们 global globalDict然而 在下面的代码中并不是这样做的解决方案 是否有
  • 在java中使用多个bufferedImage

    我正在 java 小程序中制作游戏 并且正在尝试优化我的代码以减少闪烁 我已经实现了双缓冲 因此我尝试使用另一个 BufferedImage 来存储不改变的游戏背景元素的图片 这是我的代码的相关部分 public class QuizApp

随机推荐

  • React中的条件渲染

    React中的条件渲染 Vue js中使用v if v else实现模板中的条件渲染 小程序中使用wx if wx else实现模板中的条件渲染 React中没有模板 即不需要v if 也没有指令系统 即没有v if 条件渲染需要手工实现
  • Springboot整合Mybatis之数据源配置

    spring datasource driver class name com mysql cj jdbc Driver spring datasource url jdbc mysql localhost 3306 springboot
  • androidstudio3.0解决gradle plugin 和android_apt不兼容问题

    将项目下的 classpath com neenbedankt gradle plugins android apt 1 8 删掉 和modul下的apply plugin com neenbedankt android apt 删掉 ap
  • opengl嵌入pyqt5编译的分割窗口中

    opengl嵌入pyqt5编译的分割窗口中 向大部分商业仿真软件一样 使用opengl显示三维模型 首先需要将opengl的窗口嵌入到pyqt5编译的界面中 下面是一个小例子 python view plain copy from PyQt
  • AI-视频换脸

    本文涉及到的代码均已放置在我的github中 gt 链接 环境 Anaconda 集成 python 3 6 5 主要使用了 dlib numpy opencv 调用为cv2 os这四个库 录制 截屏 FSCapture 8 0 目的 将视
  • pycharm配置PyQt5,以及创建第一个项目

    认你已经安装好了pycharm 也正确安装了PyQt5 否则 请移步https www cnblogs com longbigbeard p 9628102 html来安装PyQt5 下一步 Tools gt External Tools
  • CTFHub---xss 反射型

    反射型 反射型xss攻击 Reflected XSS 又称为非持久性跨站点脚本攻击 它是最常见的类型的XSS 攻击代码的工作方式可以分为三个类型 1 持久型跨站 最直接的危害类型 跨站代码存储在服务器 数据库 2 非持久型跨站 反射型跨站脚
  • 特征工程的建立过程

    1 特征工程 1 1 了解特征工程 数据挖掘 二八原则 80 的精力 gt 选取特征 20 的精力 gt 模型融合等 基于数据分析与探索提取潜在有价值的特征 特征工程重要性 特征越好 模型的性能越出色 特征越好 构建的模型越简单 特征越好
  • 清除浮动的五种方法

    为什么要清除浮动 因为往往浮动后的子元素因为脱离了标准流 不能自动撑起父元素的高度 所以会对后续布局产生影响 对此清除浮动不如理解为清除浮动产生的影响更为合理 例如 我们设置了两个盒子如图所示 粉色为父盒子 只有宽度没有高度 蓝色盒子有宽有
  • v-for和v-if不能同时使用(原因和解决方法)

    原因 当v for和v if同时使用时 VSCode会提示报错 这是因为v for的优先级比v if的优先级高 每一次遍历 再一个一个决定是否需要显示出来 渲染了多余的DOM节点 这会影响性能 解决 1 加一个
  • 【网络结构设计】1、ResNeXt

    文章目录 一 背景 二 方法 三 效果 论文 Aggregated Residual Transformations for Deep Neural Networks 代码 https github com miraclewkf ResNe
  • 前端浏览器报错:Invalid prop: type check failed for prop "border". Expected Boolean, got String.

    用elementUI写vue 项目 在浏览器调试的时候报了这个错误 原因是给表格加border true 让表格得到竖直的框线 插件希望得到的是一个布尔值 但是得到的是true的字符串 解决办法 在border true 前加上一个冒号
  • vue---深度修改样式

    scss parent v deep children1 样式 children2 样式
  • Sharding-Jdbc实现读写分离、分库分表

    1 概览 ShardingSphere Jdbc定位为轻量级Java框架 在Java的Jdbc层提供的额外服务 它使用客户端直连数据库 以jar包形式提供服务 可理解为增强版的Jdbc驱动 完全兼容Jdbc和各种ORM框架 2 MySQL主
  • LINUX下MYSQL密码正确但无法本地登录

    如果可以远程登录 但无法本地登录 报错为1045 可能出错原因和我一样 配置过远程连接 修改过user表中的host字段 而mysql默认user为localhost 不匹配于是报错 解决办法 1 启动mysql时跳过密码问题 打开my c
  • git:远程仓库

    远程仓库是指托管在网络服务器上的项目仓库 可能会有好多个项目仓库 其中有些你只能读 另外有些可以写 同他人协作开发某个项目时 需要管理这些远程仓库 以便推送或拉取数据 分享各自的工作进展 假设远程仓库有一个默认远程分支 dev 如果将其克隆
  • Ubuntu下SSH设置,实现远程登录

    网上有很多介绍在Ubuntu下开启SSH服务的文章 但大多数介绍的方法测试后都不太理想 均不能实现远程登录到Ubuntu上 最后分析原因是都没有真正开启ssh server服务 最终成功的方法如下 Ubuntu 下安装 OpenSSH Se
  • nginx的配置转发

    有这样一个需求 项目中跳转到某个地址 但这个地址不想暴露给用户 因此我们想到要做一层代理 通过项目某个路径直接用ngnix代理到这个地址 查询相关文档后 发现方案如下 用return 302 1 2 3 location myBaidu r
  • 【SpringBoot】过滤器,监听器,拦截器介绍

    文章目录 一 简介 1 过滤器 2 拦截器 3 监听器 二 如何创建 1 过滤器 2 监听器 3 拦截器 三 总结 一 简介 通过两幅图我们可以理解拦截器和过滤器的特点 1 过滤器 过滤器是在请求进入tomcat容器后 但请求进入servl
  • 环形缓冲区– Disruptor背后的数据结构

    环形缓冲区 Disruptor背后的数据结构 Disruptor是一个高性能的库 用于在线程之间传递消息 该库由LMAX Exchange公司在几年前开发和开源 他们创建了此软件来处理其零售金融交易平台中的巨大流量 超过600万TPS 在2