问题标签 [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.

0 投票
2 回答
555 浏览

java - Windows C++ 等效于 Java 的 LockSupport.parkNanos()

我需要在 Win7 x64 上实现与此功能相同的功能。

我最初使用过SwitchToThread(),但这不起作用,因为它在极端条件下会导致死锁。我能找到的唯一选择是Sleep(),这可能会成为性能杀手,因为它仅适用于毫秒分辨率,我仍然不确定它是否与LockSupport.parkNanos().

我发现 Java 以纳秒间隔调度(如果发生这种情况的话)线程的能力很可疑,所以我实现了我只能假设它们会做的事情......旋转。但是我不确定这是否能解决问题,它可能只是延迟不可避免的事情,因为 Java 函数似乎需要 JVM 的干预才能工作。没有可用的源代码parkNanos;它在本地 Sun 库中实现。

调用代码如下所示:

FWIW,我正在将 LMAX 的 Disruptor 模式移植到 C++。当一个线程进入SingleThreadedClaimStrategy::WaitForFreeSlotAt()而另一个线程进入BlockingWaitStrategy::WaitFor(没有超时)时,就会发生死锁。当 RingBuffer 的大小很小时,死锁会更加明显...... 1、2、4、8 等。

线程是通过正常CreateThread方式创建的。

编辑:我写这篇文章的时候已经很晚了,所以这里有更多信息。RingBuffer 持有__int64s。我有一个生产者线程和一个消费者线程。Consumer 线程还生成一个 Timer 线程,该线程每秒轮询 Consumer 以获取它上次消费的事件的序列号。当消费者没有进展并且生产者也没有完成时,就会出现这样的情况。Producer 只是在循环中运行了几亿次,发布了一个计数器。所以我的输出看起来像这样:

它只有在发布模式下才能真正重现,一切都针对速度进行了优化。

0 投票
1 回答
1752 浏览

java - 破坏者:日记示例

我对关于日志步骤的最常见(或推荐)的中断器实现感到好奇。我最常见的问题是:

  • 它是如何实际实现的(通过示例)?
  • 使用 JPA 是否明智?
  • 什么数据库是常用的(由已经使用破坏者实施项目的社区)?
  • 在中间处理程序(EventProcessors)中使用是否明智,因此应该保存每条消息的状态,而不是在业务逻辑流程之前和之后?

顺便说一句(我很抱歉,我知道这与日志步骤无关),在 eventHandler 过程中从 RingBuffer 中删除消息的正确方法是什么(假设消息已死/过期并且应该由整个过程)。我想知道类似于死信通道模式的东西。

干杯!

0 投票
2 回答
816 浏览

disruptor-pattern - 是否可以在不使用固定长度数组的情况下使用 Disruptor/Ringbuffer 模式?

我们有一个具有固定长度数组的 Disruptor 实现。是否可以实现一个不依赖于该数组,而是包含(可能是自描述的)可变长度对象列表的模式版本。例如,Protobuf 对象的 Ringbuffer?

我知道固定长度数组用于“预分配”步骤,但我认为可以用一个或多个对象池来近似该步骤。

0 投票
2 回答
2480 浏览

java - 是否应该将 Disruptor (LMAX) 与内存和 CQRS 中的大模型一起使用?

出于性能原因,我们的系统将结构化模型(约 30 个具有多种关系的不同实体)完全保存在内存中(约 10 Gb)。在这个模型上,我们必须做 3 种操作:

  1. 更新一个或几个实体
  2. 查询特定数据(这通常需要读取数千个实体)
  3. 获取统计数据(使用了多少内存,多少种查询等)

目前,该体系结构是一种相当标准的体系结构,具有用于使用共享模型的 servlet 的线程池。在模型内部有很多并发集合,但仍然有很多等待,因为一些实体“更热”并且大多数线程想要读/写它们。另请注意,通常查询比写入更耗费 CPU 和时间。

我正在研究切换到 Disruptor 架构的可能性,将模型保持在一个线程中,将所有可能的(有效性检查、审计等)从模型中移出一个单独的消费者。

第一个问题当然是:这有意义吗?

第二个问题是:理想情况下,写请求应该优先于读请求。在破坏者中获得优先权的最佳方式是什么?我在考虑 2 个环形缓冲区,然后尝试从高优先级的缓冲区读取比从低优先级的缓冲区读取的频率更高。

澄清这个问题比关于 LMAX Disruptor 的实际代码更具架构性。

更新更多细节

数据是一个复杂的领域,许多不同类型(~20)的实体(>100k)在它们之间以具有许多不同集合的树结构链接。

查询通常涉及遍历数千个实体以找到正确的数据。更新很频繁,但非常有限,例如一次 10 个实体,因此在整个数据中变化不大(例如每小时 20%)。

我做了一些初步测试,看起来并行查询模型的速度优势超过了偶尔的写锁延迟。

0 投票
2 回答
1188 浏览

c# - 为什么我的破坏者示例如此缓慢?

我从 Stack Overflow 问题Disruptor.NET 示例中获取了代码示例,并将其修改为“测量”时间。完整清单如下:

输出是:

因此,将数据从一个线程传递到另一个线程大约需要 50 微秒。但它一点也不快!“当前版本的 Disruptor 可以在线程之间以每秒 100 万条消息的速度执行约 50 ns。” 所以我的结果比预期的慢 1000 倍。

我的示例有什么问题,如何实现 50 ns 的速度?

我已经修改了上面的程序,现在收到 1 微秒的延迟,这要好得多。但是,我仍在等待disruptor模式专家的回复。我正在寻找一个可以证明我实际上可以在 50 ns 内传递数据的示例。

BlockingCollection此外,我使用平均 14 微秒编写了相同的测试,这证明它Disruptor更快:

使用 BlockingCollection:

使用干扰器:

BlockingCollection 代码:

破坏者代码:

0 投票
2 回答
2949 浏览

c# - 具有 1 个发布者和 4 个并行消费者的破坏者示例

在这个例子中https://stackoverflow.com/a/9980346/93647和这里为什么我的破坏者例子这么慢?(在问题结束时)有 1 个发布者发布项目和 1 个消费者。

但就我而言,消费者工作要复杂得多,需要一些时间。所以我想要 4 个并行处理数据的消费者。

例如,如果生产者生产数字:1,2,3,4,5,6,7,8,9,10,11..

我希望消费者 1 捕获 1,5,9,...消费者 2 捕获 2,6,10,...消费者 3 捕获 3,7,11,...消费者 4 捕获 4,8,12...(不完全是这些数字,想法是数据应该并行处理,我不在乎哪个消费者处理了哪个特定数字)

请记住,这需要并行完成,因为在实际应用程序中,消费者工作非常昂贵。我希望消费者在不同的线程中执行以使用多核系统的强大功能。

当然,我可以只创建 4 个环形缓冲区并将 1 个消费者附加到 1 个环形缓冲区。这样我就可以使用原始示例。但我觉得这不会是正确的。创建 1 个发布者(1 个环形缓冲区)和 4 个消费者可能是正确的——因为这是我需要的。

在谷歌群组中添加一个非常相似的问题的链接:https ://groups.google.com/forum/#!msg/lmax-disruptor/-CLapWuwWLU/GHEP4UkxrAEJ

所以我们有两个选择:

  • 一环多个消费者(每个消费者都会在每次添加时“唤醒”,所有消费者应该有相同的WaitStrategy)
  • 许多“一环 - 一个消费者”(每个消费者只会在它应该处理的数据上唤醒。每个消费者可以有自己的 WaitStrategy)。
0 投票
2 回答
935 浏览

c# - 我应该同步对破坏者 Next/Publish 方法的访问吗?

我没有提供完整的列表,因为下面的代码对于那些熟悉破坏者的人来说已经足够了。问题是调用NextPublish方法是否是线程安全的。在下面的示例之间,正确的示例是什么?注意Attach可以同时从不同的线程调用。我有多个消费者。

示例 1。锁定一切:

例 2。锁定下一个:

例 3。无锁

0 投票
2 回答
1516 浏览

c# - 我的中断网代码比 BlockingCollection 慢

Disruptor 应该比 BlockingCollection 快得多。

在我之前的问题中,为什么我的破坏者示例如此缓慢?我写了两个测试。Disruptor花费了大约 1 微秒(或更短),而 BlockingCollection 花费了大约 14 微秒。

所以我决定Disruptor在我的程序中使用它,但是当我实现它时,我发现现在Disruptor花费大约50微秒,而 BlockingCollection 仍然花费14-18微秒。

我已将我的生产代码修改为“独立测试”,Disruptor但仍花费 50 微秒。为什么?

下面是一个简化的测试。在这个测试中,我有两个选择。第一个选项是Sleep for 1 ms。然后Disruptor花费 30-50 微秒来交付。第二个选项是模拟活动。然后Disruptor花费 7 微秒来交付。相同的测试BlockingCollection在 14-18 微秒内得出结果。那么为什么 Disruptor 不比 BlockingCollection 快呢?

在我的实际应用程序中Disruptor花费 50 微秒来交付太多的东西!我希望它传递消息的速度应该比 1 微秒快得多。

旧代码。现在应该忽略:

输出:

0 投票
1 回答
441 浏览

disruptor-pattern - 如何设置中断者的 ClaimStrategy 缓冲区大小

现在我正在使用disruptor,我得到一个consumer-productor的简单示例。它运行完美,但我不知道buffersize的含义,我应该设置它的大小?

私有静态最终 int BUFFER_SIZE = 4;

BUFFER_SIZE 是什么意思?

0 投票
2 回答
1399 浏览

java - 干扰器:门控序列

我正在学习 Java 中的 Disruptor。我不明白门控序列的含义。我知道它的核心部分是环形缓冲区,每个缓冲区都与一个序列号相关联。