系统性能典型案例分析:高性能队列Disruptor,一文深入理解

背景

Disruptor是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题(在性能测试中发现竟然与I/O操作处于同样的数量级)。基于Disruptor开发的系统单线程能支撑每秒600万订单,2010年在QCon演讲后,获得了业界关注。2011年,企业应用软件专家Martin Fowler专门撰写长文介绍。同年它还获得了Oracle官方的Duke大奖。

Disruptor是一款高性能的有界内存队列,其中包括Apache Storm、Camel、Log4j 2在内的很多知名项目都应用了Disruptor以获取高性能,Disruptor 项目团队曾经写过一篇论文,详细解释了其原因,可以总结为如下:

  • 内存分配更加合理,使用 RingBuffer 数据结构,数组元素在初始化时一次性全部创建,提升缓存命中率;对象循环利用,避免频繁 GC。
  • 能够避免伪共享,提升缓存利用率。3. 采用无锁算法,避免频繁加锁、解锁的性能消耗。
  • 支持批量消费,消费者可以无锁方式消费多个消息。

今天我们先来聊一聊 Disruptor 怎么使用的,好让你们先对 Disruptor 有个提前的认识。

下面是官方出示的代码,我稍微修改了一下,相较而言,Disruptor 的使用比 Java SDK提供 BlockingQueue 要难懂一些,但是总体上来说是差不多的,其大致情况如下:

  • 生产者生产的对象称为 Event,使用Disruptor 必须自定义 Event,例如示例代码的自定义 Event 是 LongEvent,这是在 Disruptor 中的。
  • 需要传入一个 EventFactory才能构建 Disruptor 对象除了要指定队列大小,还示例代码中传入的是LongEvent::new;
  • 消费 Disruptor 中的 Event 需要通过 handleEventsWith() 方法注册一个事件处理器,发布 Event 则需要通过 publishEvent() 方法。
/* 自定义 Event */
class LongEvent {
	private long value;
	public void set( long value )
	{
		this.value = value;
	}
}
/* 指定 RingBuffer 大小, 9 // 必须是 2 的 N 次方 */
int bufferSize = 1024;

/* 构建 Disruptor */
Disruptor<LongEvent> disruptor
	= new Disruptor<>(
LongEvent: : new,
	bufferSize,
	DaemonThreadFactory.INSTANCE );

/* 注册事件处理器 */
disruptor.handleEventsWith(
	(event, sequence, endOfBatch) - >
	System.out.println( "E: " + event ) );

/* 启动 Disruptor */
disruptor.start();

/* 获取 RingBuffer */
RingBuffer<LongEvent> ringBuffer
	= disruptor.getRingBuffer();
/* 
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值