LMAX 的颠覆者模式如何运作?

2023-12-11

我正在尝试理解破坏者模式。我观看了 InfoQ 视频并尝试阅读他们的论文。我知道涉及一个环形缓冲区,它被初始化为一个非常大的数组,以利用缓存局部性,消除新内存的分配。

听起来好像有一个或多个原子整数来跟踪位置。每个“事件”似乎都有一个唯一的 ID,并且通过查找其相对于环的大小的模数等来找到它在环中的位置。

不幸的是,我对它是如何工作的没有直观的感觉。我做过很多交易应用并研究过演员模型,查看了SEDA等。

在他们的演讲中,他们提到这种模式基本上就是路由器的工作方式;但是我也没有找到关于路由器如何工作的任何好的描述。

有一些好的指示可以提供更好的解释吗?


Google Code 项目确实参考技术论文关于环形缓冲区的实现,但是对于想要了解其工作原理的人来说,这有点枯燥、学术性和困难。然而,有一些博客文章已经开始以更易读的方式解释内部结构。有一个环形缓冲区的解释这是颠覆者模式的核心,消费者壁垒描述(与从干扰器读取相关的部分)和一些有关处理多个生产者的信息可用的。

对 Disruptor 最简单的描述是:它是一种以最有效的方式在线程之间发送消息的方法。它可以用作队列的替代品,但它也与 SEDA 和 Actor 共享许多功能。

与队列相比:

Disruptor 提供将消息传递到另一个线程的能力,并在需要时唤醒它(类似于 BlockingQueue)。然而,有 3 个明显的差异。

  1. Disruptor 的用户通过扩展 Entry 类并提供一个工厂来进行预分配来定义如何存储消息。这允许内存重用(复制),或者 Entry 可以包含对另一个对象的引用。
  2. 将消息放入 Disruptor 是一个两阶段的过程,首先在环形缓冲区中声明一个槽,为用户提供可以填充适当数据的条目。然后必须提交该条目,这种两阶段方法对于灵活使用上述内存是必要的。正是提交使消息对消费者线程可见。
  3. 消费者有责任跟踪已从环形缓冲区消费的消息。将这一责任从环形缓冲区本身移开有助于减少写入争用量,因为每个线程都维护自己的计数器。

与演员相比

Actor 模型比大多数其他编程模型更接近 Disruptor,特别是如果您使用提供的 BatchConsumer/BatchHandler 类。这些类隐藏了维护所使用的序列号的所有复杂性,并在重要事件发生时提供一组简单的回调。然而,存在一些细微的差异。

  1. Disruptor 使用 1 线程 - 1 消费者模型,其中 Actor 使用 N:M 模型,即您可以拥有任意数量的 Actor,并且它们将分布在固定数量的线程(通常每个核心 1 个)上。
  2. BatchHandler 接口提供了一个额外的(并且非常重要的)回调onEndOfBatch()。这允许缓慢的消费者,例如那些执行 I/O 将事件一起批处理以提高吞吐量的人。可以在其他 Actor 框架中进行批处理,但是由于几乎所有其他框架在批处理结束时都不提供回调,因此您需要使用超时来确定批处理的结束,从而导致延迟很差。

与SEDA相比

LMAX 构建了 Disruptor 模式来取代基于 SEDA 的方法。

  1. 它相对于 SEDA 的主要改进是并行工作的能力。为此,Disruptor 支持将相同的消息(以相同的顺序)多播给多个消费者。这避免了管道中对分叉阶段的需要。
  2. 我们还允许消费者等待其他消费者的结果,而不必在他们之间放置另一个排队阶段。消费者可以简单地查看它所依赖的消费者的序列号。这避免了管道中连接阶段的需要。

与内存屏障相比

另一种思考方式是将其视为结构化、有序的内存屏障。其中生产者屏障形成写屏障,而消费者屏障形成读屏障。

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

LMAX 的颠覆者模式如何运作? 的相关文章

  • Hashmap并发问题

    我有一个哈希图 出于速度原因 我希望不需要锁定 假设我不介意过时的数据 同时更新它和访问它会导致任何问题吗 我的访问是获取 而不是迭代 删除是更新的一部分 是的 这会导致重大问题 一个例子是向散列映射添加值时可能发生的情况 这可能会导致表重
  • 在 Java EE 中手动启动新线程安全吗?

    对于在会话范围内的 JSF 托管 bean 中生成线程是否安全 我找不到明确的答案 线程需要调用无状态 EJB 实例 依赖注入到托管 bean 上的方法 背景是我们有一份需要很长时间才能生成的报告 由于我们无法更改服务器设置 这导致 HTT
  • 是否有一种更简单的方法可以并行运行命令,同时在 Windows PowerShell 中保持高效?

    此自我回答旨在为那些受困于 Windows PowerShell 并由于公司政策等原因而无法安装模块的用户提供一种简单且高效的并行替代方案 在 Windows PowerShell 中 built in可用的替代方案local并行调用是St
  • 与通道相比,sync.WaitGroup 的优势是什么?

    我正在开发一个并发 Go 库 我偶然发现了 goroutine 之间两种不同的同步模式 其结果相似 等待组 https play golang org p ZYPLlcp16TZ package main import fmt sync t
  • mongodb/node.js 中单文档并发读写操作的问题

    编辑 6 15我尝试运行相同的代码 在调用之前添加延迟 doSafePush 再次收到 ConcurrencyDBError 时 即执行return when resolve wait delay 35 then function doSa
  • scala.concurrent.blocking - 它实际上做了什么?

    我花了一段时间学习 Scala 执行上下文 底层线程模型和并发性的主题 你能解释一下通过什么方式吗scala concurrent blocking 调整运行时行为 and 可以提高性能或避免死锁 如中所述scaladoc http www
  • 如何读取 UDP 连接直至超时?

    我需要读取 UDP 流量 直到超时 我可以通过在 UDPConn 上调用 SetDeadline 并循环直到出现 I O 超时错误来做到这一点 但这看起来很黑客 基于错误条件的流量控制 下面的代码片段看起来更正确 但并没有终止 在生产中 这
  • shell脚本中是否有互斥/信号量机制?

    我正在 shell 脚本中寻找互斥 信号量 并发机制 考虑以下情况 除非 a 用户不关闭共享文件 否则 b 用户应该无法打开 更新它 我只是想知道如何在 shell 脚本中实现互斥量 信号量 临界区等 在 shell 脚本中实现锁定机制 文
  • 是否可以保证 WaveFront (OpenCL) 中的所有线程始终同步?

    众所周知 有WARP 在CUDA中 和WaveFront 在OpenCL中 http courses cs washington edu courses cse471 13sp lectures GPUsStudents pdf http
  • 这个单例能够抵抗序列化和反射攻击吗?

    以下代码是否能够抵抗序列化和反射攻击 public class Example private static Example instance new Example private Example public static Exampl
  • 在 Python 中发送 100,000 个 HTTP 请求的最快方法是什么?

    我正在打开一个包含 100 000 个 URL 的文件 我需要向每个 URL 发送 HTTP 请求并打印状态代码 我正在使用 Python 2 6 到目前为止 我已经了解了 Python 实现线程 并发的许多令人困惑的方式 我什至看过蟒蛇一
  • Java 中的 64 位赋值在 32 位机器上是原子的吗?

    如果我有这样的代码 long x x 0xFFFFFFFFL 如果我在 32 位机器上运行此代码 它是否保证是原子的 或者读取 x 的不同线程是否可能获得不完整 垃圾值 这是简短的摘要 作为参考 读 写是ALWAYS原子 即使在 64 位实
  • 控制启动时的竞争条件

    我有一些代码想要执行一些一次性初始化 但这段代码没有明确的生命周期 因此在初始化完成之前 我的逻辑可能会被多个线程调用 所以 我想基本上确保我的逻辑代码 等待 直到初始化完成 这是我的第一次剪辑 public class MyClass p
  • Java Thread.sleep() 实现

    有人可以帮我理解 Thread sleep 函数是如何实现的吗 当指定时间过去或其他线程中断时 线程恢复 唤醒 我有兴趣了解其工作背后的设计模式 据说睡眠对CPU消耗没有影响 当前线程是否已添加到侦听器列表中 什么时候检查中断标志 调度程序
  • 异步/等待 - 是*并发*吗?

    我一直在考虑 C 5 中新的异步内容 并且出现了一个特殊问题 据我了解 await关键字是一个简洁的编译器技巧 语法糖来实现连续传递 http en wikipedia org wiki Continuation passing style
  • Java 中具有可重入锁和条件的生产者消费者场景

    我使用可重入锁和条件编写了一个生产者消费者程序 它工作正常 但我不太确定实施是否正确 此外 它似乎不是最佳的 有人可以验证这是否是正确的实现 此外您能告诉我如何优化它 比如 在真正需要的地方锁定 public class TestRL st
  • 在并行任务与异步任务上使用 Task.Wait

    在章节中4 4 动态并行性 在史蒂芬 克利里的书中C 中的并发食谱 它说如下 并行任务可能会使用阻塞成员 例如Task Wait Task Result Task WaitAll 和 Task WaitAny 相比之下 异步 任务应该避免阻
  • 何时在多线程中使用 易失性?

    如果有两个线程访问全局变量 那么许多教程都说使该变量成为易失性的 以防止编译器将变量缓存在寄存器中 从而无法正确更新 然而 两个线程都访问共享变量需要通过互斥体进行保护 不是吗 但在这种情况下 在线程锁定和释放互斥体之间 代码位于关键部分
  • 在使用 stop_token 等待条件变量_any 时是否需要拥有锁来请求停止?

    在等待条件变量时 更改谓词状态的线程必须拥有锁 因此在唤醒期间不会错过更新 根据文档 这是必要的 即使在使用原子变量时也是如此 不过我不确定是否request stop 已经正确处理了 那么问题是 这两个选项中哪一个是正确且符合标准的呢 j
  • 并发集合和独特元素

    我有一个并发BlockingCollection具有重复的元素 如何修改它以添加或获取不同的元素 默认后备存储BlockingCollection is a ConcurrentQueue 正如其他人指出的那样 使用它来添加不同的项目相当困

随机推荐

  • 根据第一列将两个文件合并为一个

    我有两个文件 两者格式相同 两列都包含一个数字 例如 file 1 1 00 99 2 00 343 3 00 34 10 00 343 file 2 1 00 0 4 2 00 0 5 3 00 0 34 10 00 0 9 我想生成以下
  • 检查 nsstring 中的多个字符

    我有一个字符串 我想检查该字符串中的多个字符 下面的代码我对一个字符工作正常 如何检查多个字符 NSString yourString ABCCDEDRFFED For example NSScanner scanner NSScanner
  • Excel单元格样式问题

    我使用下面的代码从 XLSX 文件中获取日期值 这对于某些 XLSX 文件来说工作得非常好 但它没有给出 XLSX 文件中的确切日期格式 此问题针对某些文件 例如 我有这样的约会21 01 2016 dd mm yyyy 但读完后 它给出的
  • 如何与许多父母建立多重自我参照关系?

    我想以最简单的方式建模以下内容 一项技能有许多依赖技能 每项技能都应该独立存在 并且一项技能可能具有其他作为必备技能的技能 例如 Skill Front End Development Has Dependent Skills gt HTM
  • jQuery $.post 在 Chrome 中失败,数据不为空。 NETWORK_ERR:XMLHttpRequest 异常 101

    这是代码 ajaxSetup async false post save a 1 function res random html res text error function jqxhr status err random html e
  • 两个尺寸相同但分辨率不同的屏幕

    假设我们有两台屏幕尺寸相同但分辨率不同的 Android 设备 以下是否正确 如果使用 dp 单位设置所有视图的大小 则两个屏幕将显示相同数量的内容 唯一的区别是视图的清晰度 如果屏幕的物理尺寸相同 但 dpi 不同 并且您使用了 dp 与
  • Unity 中的随机排列数组

    我想打乱我的数字array变量一次 所以我打电话给我的Shuffle方法来自Start 然后 我尝试通过更新访问已打乱顺序的数组 但我无法这样做 我怎样才能访问它 有没有其他方法可以对数组进行一次洗牌 然后永远使用它 private Sys
  • 从 PreferenceScreen 到 DialogPreference

    我的应用程序有一个设置菜单 它实际上是一个 PreferenceActivity 创建时 如果未设置布尔值 我想转到设置该值的 DialogPreference 我尝试有意这样做 但应用程序强制关闭并显示以下错误消息 E Android运行
  • 使用 powershell 脚本中的参数运行 shell 命令

    我需要使用 bcp 从远程 SQL 数据库中提取并保存一些表 我想编写一个 powershell 脚本来为每个表调用 bcp 并保存数据 到目前为止 我有这个脚本为 bcp 创建必要的参数 但是我不知道如何将参数传递给 bcp 每次我运行脚
  • 无法在 JTable 的单个单元格中添加两个按钮

    我正在尝试创建一个动态表 从数据库中获取数据并将这些数据添加到单独的行中 我想在每行 动态 添加一个额外的单元格 其中包含两个按钮 并且单击这些按钮时 某些事件应该仅发生在相应的行上 P S 我已经设法从数据库中获取数据并将其添加到表中 这
  • 测试上传的应用程序(默认版本除外)

    除了 默认 版本之外 您可以测试应用程序的上传版本吗 我听说它可以是 WoLpHGoogle App Engine 版本号 但我在仪表板或 doco 中找不到它 如果应用程序的版本是2你的应用程序 URL 是appname appspot
  • Android 应用程序无法识别 setRedirectStrategy?

    我正在尝试使用 apache 的 httpclient 库编写一个 android 应用程序 尽管此代码片段在实际的 Java 项目中编译时会出现错误 The method setRedirectStrategy new DefaultRe
  • 我可以使用多重绑定进行文本搜索吗

    我在 mvvm wpf 应用程序中有以下组合框 我需要在此实现 文本搜索 以及多重绑定 有人可以帮我吗
  • 使用任务取消长时间运行的 IO/网络操作的好方法是什么?

    我一直在研究 net 4 0 中的任务及其取消 我喜欢 TPL 尝试以合作的方式正确处理取消问题 然而 当任务内的调用发生阻塞并且需要很长时间时该怎么办 例如 IO 网络 显然取消写入是危险的 但这些只是例子 示例 我该如何取消此操作 Do
  • 执行 Parallel.For 从数组计算数据的正确方法

    想要 对 x 求和并对 x x 求和 其中 x 行 i 因为多个线程想要读 写 sumAll 和 sumAllQ 所以我需要锁定其访问权限 问题是锁类型在这里序列化了事物 我需要将此操作拆分为 Environment ProcessorCo
  • 无法将值插入表视图 - JavaFx

    我是 JavaFx 新手 我正在尝试创建一个表视图 并且 fxml 是使用场景生成器创建的 如果我运行该程序 该表不会获取值 我发现这个问题在某种程度上符合我的要求 javaFX 2 2 无法从控制器填充表 但我的代码也与之匹配 但我仍然无
  • NHibernate 标准:“From”子句后的子查询

    如何使用 Criteria 编写以下 SQL select b Name as Batch b Capacity as Capecity a tStudent as Admit b Capacity a tStudent as Availa
  • 在 d3.js 中显示圆弧末端的文本

    经过一整天的煎熬我的大脑 最后决定来这里问问 我正在尝试在 d3 js 中的圆弧末尾附加文本 我尝试使用 arc cenriod 但这将文本保留在圆弧的中心 我想在圆弧末尾显示文本 var pi Math PI width 600 heig
  • 以管理员身份运行 BAT(无快捷方式)

    因此 我试图创建一个 bat 来任务杀死 Win7 中的特定程序 我正在使用命令 taskkill f im LCore exe bat 需要以管理员身份运行才能工作 因此我创建了一个快捷方式 以便按照另一个线程中指定的方式在管理员模式下自
  • LMAX 的颠覆者模式如何运作?

    我正在尝试理解破坏者模式 我观看了 InfoQ 视频并尝试阅读他们的论文 我知道涉及一个环形缓冲区 它被初始化为一个非常大的数组 以利用缓存局部性 消除新内存的分配 听起来好像有一个或多个原子整数来跟踪位置 每个 事件 似乎都有一个唯一的