一个线程每秒处理600万笔交易是如何做到的?
LMAX交易所是世界上领先的机构外汇交易所,他们已拥有全球300多家大型基金和经纪商作为机构客户群,以及25家全球主要银行和非银行机构作为流动性提供商。要面对这么多的客单量,他们自主研发的系统,每秒可处理600万个订单。所有订单都是撮合形式成交,超过90%的交易在小于20毫秒之内执行。
那它是如何做到一个线程每秒撮合生成600万个订单?原因有二:
第一, 业务逻辑处理器完全是运行在内存中,速度够快,这个大家都很容易理解。
第二,使用自主研发的Disruptor并发框架组件,能够在无锁的情况下实现网络的Queue并发操作。
Disruptor这个并发框架组件是如何做到这么高的并发速度的?它与Java自带的多线程并发框架有何相似和区别呢?
Disruptor与BlockingQueue有什么相同点呢?
从功能上来看,Disruptor 是实现了“队列”的功能,而且是一个有界队列。那么它的应用场景自然就是“生产者-消费者”模型的应用场合了。
我们知道 BlockingQueue 是一个 FIFO 队列,生产者(Producer)往队列里发布(publish)一项事件(或称之为“消息”也可以)时,消费者(Consumer)能获得通知;如果没有事件时,消费者被堵塞,直到生产者发布了新的事件。
这就是两者的相似之处。
Disruptor与BlockingQueue有什么区别吗?LMAX给Disruptor设计了什么功能呢?
第一,Disruptor性能要比BlockingQueue好很多
针对极高的性能目标而实现的极度优化和无锁的设计,性能相比BlockingQueue高很多,当多个线程之间传递大量数据或对性能要求较高时,可以考虑使用Disruptor作为BlockingQueue的替代者,而且Disruptor一般采用一个线程做为生产者接收消息。
官方也对Disruptor和ArrayBlockingQueue的性能在不同的应用场景下做了对比,本文列出其中一组数据,数据中P代表producer,C代表consumer,ABS代表ArrayBlockingQueue:
完整的官方性能测试数据在Performance Results · LMAX-Exchange/disruptor Wiki可以看到,性能测试的代码已经包含在Disruptor的代码中,你完全可以git下来在自己的主机上测试一下看看。
第二,Disruptor事件可以多次消费
同一个“事件”可以有多个消费者,消费者之间既可以并行处理,也可以相互依赖形成处理的先后次序(形成一个依赖图),并行处理和串行处理能够相互结合实现多种处理方式。
第三,Disruptor事件内容的存储空间可以预先分配
预分配用于存储事件内容的内存空间,可以根据需求进行设置事件内容的存储长度,保证高的吞吐量。
以上就是使用Disruptor操作内存中的数据达到如此高并发的原因。