问题标签 [disruptor-pattern]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
data-structures - 破坏者模式和 NServiceBus
我一直在对高性能可靠消息传递系统的破坏者模式进行一些研究,作为 NServiceBus 的狂热用户,我想知道这是否可以实现?或者也许已经有一个实现......我只是想知道其他人对此的想法?
design-patterns - What is LMAX Disruptor Design Pattern?
Can anyone tell me what is Disruptor design pattern with simple example ? I will want to know basics of this design pattern.
concurrency - 何时使用破坏者模式,何时使用本地存储窃取工作?
以下是正确的吗?
- 如果必须以多种方式(io 操作或注释)处理每个条目,则破坏者模式具有更好的并行性能和可扩展性,因为可以使用多个消费者并行化而不会发生争用。
- 相反,如果每个条目只能以单一方式处理,工作窃取(即在本地存储条目并从其他线程窃取条目)具有更好的并行性能和可伸缩性,因为在中断模式中将条目不相交地分布到多个线程会导致争用。
(当涉及多个生产者(即CAS 操作)时,破坏者模式是否仍然比其他无锁多生产者多消费者队列(例如来自 boost )快得多?)
我的详细情况:
处理一个条目可以产生几个新条目,最终也必须处理这些条目。性能具有最高优先级,按 FIFO 顺序处理的条目具有第二优先级。
在当前的实现中,每个线程都使用本地 FIFO,并在其中添加新条目。空闲线程从其他线程的本地 FIFO 窃取工作。线程处理之间的依赖关系使用无锁、机械同理哈希表(写入时的 CAS,具有桶粒度)来解决。这导致争用非常低,但 FIFO 顺序有时会被破坏。
使用破坏者模式将保证 FIFO 顺序。但是,将条目分配到线程上会不会导致比具有工作窃取的本地 FIFO 更高的争用(例如,读取光标上的 CAS)(每个线程的吞吐量大致相同)?
我找到的参考资料
关于破坏者的标准技术文件(第 5 + 6 章)中的性能测试不包括不相交的工作分布。
https://groups.google.com/forum/?fromgroups=#!topic/lmax-disruptor/tt3wQthBYd0是我找到的关于破坏者 + 工作窃取的唯一参考。它指出如果有任何共享状态,每个线程的队列会显着变慢,但没有详细说明或解释原因。我怀疑这句话是否适用于我的情况:
- 使用无锁哈希表解析共享状态;
- 必须在消费者之间不连贯地分发条目;
- 除了工作窃取之外,每个线程只在其本地队列中读写。
architecture - LMAX 架构 - 数据增长
考虑Martin Fowler的 LMAX 架构描述中的以下场景:
我将使用一个简单的非 LMAX 示例来说明。想象一下,您正在通过信用卡订购果冻豆。<...>
在 LMAX 架构中,您可以将此操作分成两部分。第一个操作将捕获订单信息并通过向信用卡公司输出事件(请求信用卡验证)来完成。然后,业务逻辑处理器将继续为其他客户处理事件,直到它在其输入事件流中收到信用卡验证事件。在处理该事件时,它将执行该订单的确认任务。
因此,订单一直保存在内存中,直到收到付款处理结果。
现在让我们假设不是信用卡处理步骤,而是需要更多时间的步骤,例如:我们需要执行库存检查,其中有人必须物理验证我们是否有已订购的特定风味的软糖。这可能需要一个小时。
如果是这种情况,是否会导致内存中保存的数据增长,因为可能有很多订单正在等待库存状态更新事件?
可能在这种情况下,我们需要从内存中删除订单并将其作为输出事件的一部分包含在内,外部系统(库存)负责生成另一个包含订单详细信息的输入事件。
我在这种方法中看到的问题是,我们不能将库存作为业务逻辑处理器的一部分。
关于我们如何解决这个问题的想法?
java - BatchEventProcessor LMAX Disruptor Pattern 的作用
BatchEventProcessor 在 lmax 中断模式中的作用是什么?
= new BatchEventProcessor(ringBuffer,屏障,处理程序);
java - 如何使用具有多种消息类型的破坏者
我的系统有两种不同类型的消息——类型 A 和 B。每条消息都有不同的结构——类型 A 包含一个 int 成员,类型 B 包含一个 double 成员。我的系统需要将这两种类型的消息传递给众多业务逻辑线程。减少延迟非常重要,因此我正在研究使用 Disruptor 以机械方式将消息从主线程传递到业务逻辑线程。
我的问题是破坏者只接受环形缓冲区中的一种对象。这是有道理的,因为中断器预先分配了环形缓冲区中的对象。但是,通过 Disruptor 将两种不同类型的消息传递给我的业务逻辑线程也很困难。据我所知,我有四个选择:
配置中断器以使用包含固定大小字节数组的对象(如How should one use Disruptor (Disruptor Pattern) to build real-world message systems?推荐的那样)。在这种情况下,主线程必须在将消息发布到中断器之前将消息编码为字节数组,并且每个业务逻辑线程必须在接收时将字节数组解码回对象。这种设置的缺点是业务逻辑线程并没有真正共享破坏者的内存——而是从破坏者提供的字节数组中创建新对象(从而产生垃圾)。这种设置的好处是所有业务逻辑线程都可以从同一个中断器中读取多种不同类型的消息。
将中断器配置为使用单一类型的对象,但创建多个中断器,每个对象类型一个。在上面的例子中,会有两个独立的破坏者——一个用于类型 A 的对象,另一个用于类型 B 的对象。这种设置的好处是主线程不必将对象编码为字节数组,并且业务较少的逻辑线程可以共享与中断器中使用的相同的对象(不创建垃圾)。这种设置的缺点是每个业务逻辑线程必须以某种方式订阅来自多个破坏者的消息。
将中断器配置为使用包含消息 A 和 B 的所有字段的单一类型的“超级”对象。这非常不符合 OO 风格,但允许在选项 #1 和 #2 之间进行折衷。
配置中断器以使用对象引用。但是,在这种情况下,我失去了对象预分配和内存排序的性能优势。
对于这种情况,您有什么建议?我觉得选项 #2 是最干净的解决方案,但我不知道消费者是否或如何在技术上订阅来自多个破坏者的消息。如果有人可以提供如何实施选项 #2 的示例,将不胜感激!
java - 从 LinkedBlockingQueue 迁移到 LMAX 的 Disruptor
是否有一些示例代码可用于从标准LinkedBlockingQueue迁移到LMAX 的 Disruptor架构?我有一个可能从更改中受益的事件处理应用程序(单个生产者,多个消费者)。
当我的目标是最大化吞吐量而不是最小化延迟时,这是否有意义?
disruptor-pattern - Disruptor - 消费者是多线程的吗?
我对破坏者有以下问题:
- 消费者(事件处理器)没有实现他们实现 EventHandler 的任何 Callable 或 Runnable 接口,那么它们如何并行运行,所以例如我有一个中断器实现,其中有一个像这样的菱形图案
其中c1到c3可以在p1之后并行工作,C4和C5在它们之后工作。
所以通常我会有这样的东西(P1和C1-C5是runnables/callables)
但是在 Disruptor 的情况下,我的事件处理程序都没有实现 Runnable 或 Callable,那么中断器框架最终是如何并行运行它们的呢?
采取以下场景:
我的消费者 C2 需要对事件进行一些注释的 Web 服务调用,在 SEDA 中,我可以为这样的 10 个 C2 请求启动 10 个线程 [用于将消息拉出队列 + 进行 Web 服务调用并更新下一个 SEDA 队列],这将确保我不会按顺序等待 10 个请求中的每一个的 Web 服务响应,在这种情况下,我的事件处理器 C2(如果)是单个实例,将按顺序等待 10 个 C2 请求。
disruptor-pattern - 破坏者屏障是如何工作的?
LMX 破坏者的屏障如何工作?我确实了解如何将中断器与 DSL 一起使用。但是我找不到关于障碍或序列障碍如何工作的良好参考。
例如,我找到了以下链接,但不确定如何使用屏障数据结构。 http://mechanitis.blogspot.com/2011/08/dissecting-disruptor-why-its-so-fast.html
例如,new BatchEventProcessor() 接受一个 SequenceBarrier。为什么?以及如何创建一个。
failover - 破坏者模式 - 主节点和从节点如何保持同步?
在LMAX Disruptor模式中,复制器用于将输入事件从主节点复制到从节点。所以设置可能如下所示:
主节点的复制器将事件写入数据库(尽管我们可以认为比写入数据库更好的机制——这对问题陈述不是很重要)。从节点的 Receiver 从 DB 中读取数据并将事件放到从节点的环形缓冲区中。
从节点的输出事件被忽略。
现在主节点的业务逻辑处理器有可能比从节点的业务逻辑处理器慢。例如,主节点的 BL 可能位于插槽 102,而从节点可能位于 106。(这可能是因为复制器在业务逻辑处理器之前从环形缓冲区读取事件)。
在这种情况下,如果主节点发生故障并且从节点现在成为主节点,则外部系统可能会错过一些关键事件。这可能是因为节点 2 在充当从节点时忽略了其输出。
Martin Fowler 确实指出复制器的工作是保持节点同步:“之前我提到 LMAX 在集群中运行其系统的多个副本以支持快速故障转移。复制器使这些节点保持同步”
但我不确定它如何保持业务逻辑处理器同步?有任何想法吗?