标签: disruptor-pattern

LMAX的破坏模式如何运作?

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

听起来有一个或多个原子整数可以跟踪位置.每个"事件"似乎都得到一个唯一的id,它在环中的位置是通过找到与模数相关的模数等来找到的.

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

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

是否有一些更好解释的好指示?

concurrency latency actor disruptor-pattern

202
推荐指数
5
解决办法
7万
查看次数

应该如何使用Disruptor(Disruptor Pattern)来构建真实的消息系统?

由于RingBuffer预先分配给定类型的对象,如何使用单个环形缓冲区来处理各种不同类型的消息?

您无法创建要插入ringBuffer的新对象实例,这会破坏预先分配的目的.

因此,您可以在异步消息传递模式中拥有3条消息:

  1. NewOrderRequest
  2. NewOrderCreated
  3. NewOrderRejected

所以我的问题是你是如何将Disruptor模式用于现实世界的消息系统?

谢谢

链接:http: //code.google.com/p/disruptor-net/wiki/CodeExamples

http://code.google.com/p/disruptor-net

http://code.google.com/p/disruptor

disruptor-pattern

28
推荐指数
2
解决办法
8596
查看次数

Disruptor.NET示例

我正在尝试学习如何使用Disruptor.NET消息框架,我找不到任何实际的例子.有很多文章都有关于它是如何工作的图片,但我找不到任何实际的内容,并向您展示如何实现这些方法.什么是一个例子?

c# disruptor-pattern

24
推荐指数
1
解决办法
1万
查看次数

LMAX Disruptor最简单实际的示例代码

我希望我能得到最简单的示例代码,它将展示如何使用LMAX disruptor(http://code.google.com/p/disruptor/).

不幸的是,每一段代码都已过时.有人知道吗,我在哪里可以找到小而且最新的howto(最好没有DSL)?

java disruptor-pattern

17
推荐指数
3
解决办法
2万
查看次数

如何使用具有多种消息类型的破坏程序

我的系统有两种不同类型的消息 - 类型A和B.每条消息都有不同的结构 - 类型A包含int成员,类型B包含双成员.我的系统需要将两种类型的消息传递给众多业务逻辑线程.减少延迟非常重要,因此我正在研究使用Disruptor以机械同情的方式将消息从主线程传递到业务逻辑线程.

我的问题是破坏者只接受环形缓冲区中的一种类型的对象.这是有道理的,因为破坏程序在环形缓冲区中预先分配对象.但是,它也很难通过Disruptor将两种不同类型的消息传递给我的业务逻辑线程.据我所知,我有四种选择:

  1. 配置破坏程序以使用包含固定大小字节数组的对象(如何使用Disruptor(Disruptor Pattern)来构建真实的消息系统?).在这种情况下,主线程必须在将消息发布到破坏程序之前将消息编码为字节数组,并且每个业务逻辑线程必须在接收时将字节数组解码回对象.这种设置的缺点是业务逻辑线程并不真正从破坏者共享内存 - 而是从破坏者提供的字节数组创建新对象(从而创建垃圾).这种设置的好处是所有业务逻辑线程都可以从同一个破坏者中读取多种不同类型的消息.

  2. 将破坏程序配置​​为使用单一类型的对象,但创建多个破坏程序,每个对象类型一个.在上面的例子中,将有两个单独的破坏程序 - 一个用于类型A的对象,另一个用于类型B的对象.此设置的优点是主线程不必将对象编码为字节数组并且business less逻辑线程可以共享与disruptor中使用的相同的对象(没有创建垃圾).这种设置的缺点是,不知何故,每个业务逻辑线程都必须订阅来自多个破坏者的消息.

  3. 配置破坏程序使用单一类型的"超级"对象,该对象包含消息A和B的所有字段.这非常违反OO样式,但允许在选项#1和#2之间进行折衷.

  4. 配置破坏程序以使用对象引用.但是,在这种情况下,我失去了对象预分配和内存排序的性能优势.

你对这种情况有什么建议?我认为选项#2是最干净的解决方案,但我不知道消费者是否或如何从技术上订阅来自多个破坏者的消息.如果有人可以提供如何实施选项#2的示例,那将非常感谢!

java performance messaging multithreading disruptor-pattern

16
推荐指数
1
解决办法
2730
查看次数

15
推荐指数
1
解决办法
9046
查看次数

什么时候使用破坏者模式和当工作窃取本地存储?

以下是否正确?

  • 破坏者模式具有更好的并行性能和可扩展性,如果每个条目有多种方式(IO操作或注释)进行处理,因为可以使用多个消费者不争进行并行化.
  • 相反,工作窃取(即在本地存储条目和从其他线程窃取条目)具有更好的并行性能和可伸缩性,如果每个条目必须仅以单一方式处理,因为在干扰模式中将条目不相交地分配到多个线程会导致争用.

(当涉及多个生产者(即CAS操作)时,破坏者模式是否仍然比其他无锁多生产者多消费者队列(例如来自提升)快得多?)


我的情况详细:

处理条目可以产生几个新条目,这些条目也必须最终处理.性能具有最高优先级,以FIFO顺序处理的条目具有第二优先级.

在当前实现中,每个线程使用本地FIFO,在其中添加新条目.空闲线程从其他线程的本地FIFO中窃取工作.线程处理之间的依赖关系使用无锁,机械同情的哈希表(写入时的CAS,具有桶粒度)来解决.这导致相当低的争用,但FIFO顺序有时会被破坏.

使用干扰模式可以保证FIFO顺序.但是不会将条目分配到线程上导致更高的争用(例如,读取游标上的CAS),而不是工作窃取的本地FIFO(每个线程的吞吐量大致相同)?


我发现的参考文献

关于破坏者的标准技术论文(第5章+6)中的性能测试不包括不相交的工作分布.

https://groups.google.com/forum/?fromgroups=#!topic/lmax-disruptor/tt3wQthBYd0是我在disruptor +偷窃工作中发现的唯一参考.它声明如果存在任何共享状态,每个线程的队列会显着减慢,但不会详细说明或解释原因.我怀疑这句话适用于我的情况:

  • 使用无锁哈希表解析共享状态;
  • 必须在消费者之间不相交地分发条目;
  • 除了工作窃取之外,每个线程只在其本地队列中进行读写.

concurrency concurrent-programming disruptor-pattern work-stealing

11
推荐指数
1
解决办法
2267
查看次数

是什么导致这种性能下降?

我正在使用Disruptor框架对某些数据执行快速Reed-Solomon纠错.这是我的设置:

          RS Decoder 1
        /             \
Producer-     ...     - Consumer
        \             /
          RS Decoder 8 
Run Code Online (Sandbox Code Playgroud)
  • 生产者从磁盘读取2064字节的块到字节缓冲区.
  • 8个RS解码器消费者并行执行Reed-Solomon纠错.
  • 消费者将文件写入磁盘.

在disruptor DSL术语中,设置如下所示:

        RsFrameEventHandler[] rsWorkers = new RsFrameEventHandler[numRsWorkers];
        for (int i = 0; i < numRsWorkers; i++) {
            rsWorkers[i] = new RsFrameEventHandler(numRsWorkers, i);
        }
        disruptor.handleEventsWith(rsWorkers)
                .then(writerHandler);
Run Code Online (Sandbox Code Playgroud)

当我没有磁盘输出消费者(没有.then(writerHandler)部分)时,测量的吞吐量是80 M/s,一旦我添加消费者,即使它写入/dev/null,甚至不写,但它被声明为依赖消费者,性能下降到50-65 M/s.

我已经使用Oracle Mission Control对其进行了分析,这就是CPU使用率图表显示的内容:

没有额外的消费者: 没有额外的消费者

另外一个消费者: 有额外的消费者

图中的灰色部分是什么?它来自何处?我想它与线程同步有关,但我在Mission Control中找不到任何其他统计信息来指示任何此类延迟或争用.

java performance multithreading disruptor-pattern

11
推荐指数
1
解决办法
363
查看次数

从LinkedBlockingQueue迁移到LMAX'Disruptor

是否有一些示例代码用于从标准LinkedBlockingQueue迁移到LMAX的Disruptor架构?我有一个事件处理应用程序(单个生产者,多个消费者),可能会从更改中受益.

当我的目标是最大化吞吐量而不是最小化延迟时,它是否有意义?

java queue concurrency disruptor-pattern

8
推荐指数
1
解决办法
1545
查看次数

LMAX Replicator设计 - 如何支持高可用性?

LMAX Disruptor通常使用以下方法实现: 在此输入图像描述

在此示例中,Replicator负责将输入事件\命令复制到从属节点.复制一组节点需要我们应用一致性算法,以防我们希望系统在出现网络故障,主故障和从站故障时可用.

我正在考虑将RAFT一致性算法应用于此问题.一个观察结果是:"RAFT要求在复制期间将输入事件\命令存储到磁盘(持久存储)"(参考此链接)

这种观察实质上意味着我们无法执行内存中复制.因此,似乎我们可能必须结合复制器和记者的功能才能成功地将RAFT算法应用于LMAX.

有两种方法可以做到这一点:

选项1:使用复制日志作为输入事件队列 在此输入图像描述

  • 接收方将从网络读取并将事件推送到复制的日志而不是环形缓冲区
  • 单独的"阅读器"可以从日志中读取并将事件发布到环形缓冲区.
  • 可以使用RAFT跨节点复制日志.我们不需要复制器和日志,因为RAFT的复制日志已经完成了功能

我认为这个选项的缺点与我们做一个额外的数据复制步骤(接收器到事件队列而不是环形缓冲区)这一事实有关.

选项2:使用Replicator将输入事件\命令推送到从属的输入日志文件 在此输入图像描述

我想知道是否有其他解决方案来设计Replicator?人们用于复制器的不同设计选择有哪些?特别是任何可以支持内存复制的设计?

replication high-availability disruptor-pattern lmax raft

8
推荐指数
1
解决办法
1252
查看次数