disruptor(LMAX的Disruptor如何工作(stackoverflow的回答))
本文目录
- LMAX的Disruptor如何工作(stackoverflow的回答)
- 如何优雅地使用Disruptor
- disruptor框架为什么这么强大
- disruptor怎么设置多线程处理任务
- disruptor 的实现原理
LMAX的Disruptor如何工作(stackoverflow的回答)
它可以用来替代队列,同时有很多SEDA和Actors模式的特性。 和队列比较: Disruptor可以向其他线程发送消息,并在需要的时候唤醒其他线程(和BlockingQueue相似)。不过,他们之间有三个主要的区别。 2. 把消息放入Disruptor需要2个步骤,首先在ring buffer中声名一个接口,这个接口提供使用者一个可以存放正确数据的Entry。然后必须提交这个entry,要想像上文提到的那样灵活使用内存,这两个步骤是必需的。提交操作使得消费者线程可以读取消息。 3. ring buffer中被消费的消息应该由消费者来追踪。不让ring buffer来追踪消息可以减少写冲突的出现,因为每个线程都自己维护计数器。 与Actors比较 Actor模型是最接近Disruptor的程序模型,尤其是使用BatchConsumer/BatchHandler类。这些类隐藏了所有保持已消费的序列号的复杂实现的并且在重要事情发生的时候会提供一些简单的回调方法。不过有两个小小的区别。 1. Disruptor使用一个线程对应一个消费者的模型,而Actors使用多对多的模型,比如你可以拥有尽可能多的actor,它们会分布在一定数量的线程上(一般一个核心一个actor)。 2. BatchHandler接口提供了一个额外的(而且是很重要的)回调方法onEndOfBatch().它允许耗时操作,比如将I/O操作放到批处理中一起执行以提高吞吐量。使用其他Actor框架也可以作批处理,但是它们几乎都没有提供批处理执行结束的回调方法,你只能使用超时来判断批处理是否结束,从而导致差的延时。 和SEDA比较LMAX设计Disruptor模式是为了替代SEDA。 1. 和SEDA相比,disruptor主要的改进就是可以并行工作。Disruptor支持组播消息来实现这个功能,相同的消息(以一致的顺序)被发送给多个消费者。这样可以避免在管道中交叉层。 2. 消费者可以依赖其他消费者的处理结果,通过把一个队列化的层放在它们之间。一个消费者可以简单地看到自己所依赖的消费者的序列号。这样可以避免在管道中合并层。 和内存障比较 可以把dispruptor理解为一个结构化的,有序的内存障。其中生产者障碍相当于写障碍,消费者障相当于读障碍。 第二个回答(answered Jul 16 ’11 at 5:48 irreputable):首先我们来理解一下它提供的编程模型。 它有一个或多个作者和读者。有一排从旧到新的条目(从左到右)。作者可以在右侧新增条目。每个读者按从左到右的顺序读取条目。读者显然不能跳过作者先读取。 条目不能被删除。我用“读者”代替“消费者”来避免让人以为条目会被消费掉。不过我们知道最后一个读者左边的条目是没有用处的。 通常读者可以并发地独立地读取条目。但是我们可以声明读者之间的依赖关系。读者间可以有任意非环形依赖。如果读者B依赖于读者A,读者B不能跳过读者A先读取。 读者A可以注解一个条目,而读者B依赖于这个注解,所以就有了读者间的依赖。例如,A在一个条目上做一些计算,然后将结果保存到条目中的a字段。然后A前进,之后B可以读取这个条目和条目中的a。如果读者C没有依赖于A,那么C就不应该读取a。 当然了,LMAX的主要目标就是性能。Disruptor使用一个预分配的条目环。这个环足够大,但是有上限,从而不会超出容量。如果环满了,作者会一直等待,直到最慢的作者前进而腾出空间。 条目对象是预分配的并且会一直存在,以减少GC的消耗。我们不会增加新的条目对象或是删除旧的,相反的,作者会请求一个已存在的条目,填充它的字段,然后通知读者。这两个步骤真的是很简单的原子操作。setNewEntry(EntryPopulator); interface EntryPopulator{ void populate(Entry existingEntry); }预分配的条目相当于adjacent memory cells中的adjacent entries分配(很像),并且因为读者是顺序读取条目,所以利用CPU缓存很重要。 还有做了很多努力来避免锁,CAS,甚至是内存障(比如如果只有一个作者的话就使用不变的序列变量)。 写给开发者:不同注解的读者应该写到条目中不同的字段,从而避免写冲突。(事实上他们应该写在不同的缓存行中。
如何优雅地使用Disruptor
从功能上来看,Disruptor 是实现了“队列”的功能,而且是一个有界队列。那么它的应用场景自然就是“生产者-消费者”模型的应用场合了。先从了解 Disruptor 的核心概念开始,来了解它是如何运作的。下面介绍的概念模型,既是领域对象,也是映射到代码实现上的核心对象。……
disruptor框架为什么这么强大
它可以用来替代队列,同时有很多SEDA和Actors模式的特性。和队列比较:Disruptor可以向其他线程发送消息,并在需要的时候唤醒其他线程(和BlockingQueue相似)。不过,他们之间有三个主要的区别。2. 把消息放入Disruptor需要2个步骤,首先在ring...
disruptor怎么设置多线程处理任务
一个在线2k的游戏,每秒钟并发都吓死人。传统的hibernate直接插库基本上是不可行的。我就一步步推导出一个无锁的数据库操作。1. 并发中如何无锁。一个很简单的思路,把并发转化成为单线程。Java的Disruptor就是一个很好的例子。如果用java的concurrentCollection类去做,原理就是启动一个线程,跑一个Queue,并发的时候,任务压入Queue,线程轮训读取这个Queue,然后一个个顺序执行。在这个设计模式下,任何并发都会变成了单线程操作,而且速度非常快。现在的node.js, 或者比较普通的ARPG服务端都是这个设计,“大循环”架构。这样,我们原来的系统就有了2个环境:并发环境 + ”大循环“环境并发环境就是我们传统的有锁环境,性能低下。”大循环“环境是我们使用Disruptor开辟出来的单线程无锁环境,性能强大。2. ”大循环“环境 中如何提升处理性能。一旦并发转成单线程,那么其中一个线程一旦出现性能问题,必然整个处理都会放慢。所以在单线程中的任何操作绝对不能涉及到IO处理。那数据库操作怎么办?增加缓存。这个思路很简单,直接从内存读取,必然会快。至于写、更新操作,采用类似的思路,把操作提交给一个Queue,然后单独跑一个Thread去一个个获取插库。这样保证了“大循环”中不涉及到IO操作。问题再次出现:如果我们的游戏只有个大循环还容易解决,因为里面提供了完美的同步无锁。但是实际上的游戏环境是并发和“大循环”并存的,即上文的2种环境。那么无论我们怎么设计,必然会发现在缓存这块上要出现锁。3. 并发与“大循环”如何共处,消除锁?我们知道如果在“大循环”中要避免锁操作,那么就用“异步”,把操作交给线程处理。结合这2个特点,我稍微改下数据库架构。原本的缓存层,必然会存在着锁,例如:public TableCache{private HashMap《String, Object》 caches = new ConcurrentHashMap《String, Object》();}这个结构是必然的了,保证了在并发的环境下能够准确的操作缓存。但是”大循环“却不能直接操作这个缓存进行修改,所以必须启动一个线程去更新缓存,例如:private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();EXECUTOR.execute(new LatencyProcessor(logs));class LatencyProcessor implements Runnable{public void run(){// 这里可以任意的去修改内存数据。采用了异步。}}OK,看起来很漂亮。但是又有个问题出现了。在高速存取的过程中,非常有可能缓存还没有被更新,就被其他请求再次获取,得到了旧的数据。
disruptor 的实现原理
基本原则就三条:
RingBuffer 复用内存,减少分配新空间带来的时间和空间损耗。
单生产者对N消费者当然不用锁,一个只写,N个只读。
Busy Spin(疯狂死循环)是多核架构上最快的通信方法,比所有要经 kernel 走信号量之类都快。
此外 它还解决伪共享问题。这对于应用也有相当的性能提升。
更多文章:

软件java是什么意思(JAVA是什么软件主要是干什么用的)
2025年3月13日 10:20

CSS中font是什么意思?求美国加州Fontana和Bloomington这两个城市的气候
2025年3月7日 13:00

domino(如何安装或删除domino服务器作为Windows的服务)
2025年2月28日 08:50

framework笔记本官网(win7笔记本电脑程序与功能这么没有net framework)
2025年2月17日 14:20

modbustcp(安川modbustcp协议是直接可以使用么)
2025年3月18日 08:30

servu安装教程(怎样在虚拟机XP中安装Serv-u软件,利用Serv-u发布ftp站点)
2025年3月13日 21:20

fields音标(英语A CDR is composed of fields怎么翻译)
2025年4月2日 17:30

pycharm和eclipse选哪个(写python时用什么编辑器好)
2025年2月17日 09:10

js中 将 数字格式化为 小数点后保留2位 怎么弄?js格式化
2025年2月10日 15:50

the British Isles是什么意思?Isle怎么读
2025年3月29日 01:40