06 高性能无锁队列 Disruptor.md

Disruptor 是英国外汇交易公司 LMAX 开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题,因其出色的性能表现获得 2011 Duke’s 程序框架创新奖。

A High Performance Inter-Thread Messaging Library 项目地址:LMAX Disruptor

介绍

从数据结构上来看,Disruptor 是一个支持生产者/消费者模式的环形队列。能够在无锁的条件下进行并行消费,也可以根据消费者之间的依赖关系进行先后消费次序。

Disruptor 高效原理:

  1. Disruptor 使用了一个 RingBuffer 替代队列,用生产者消费者指针替代锁。

  2. 生产者消费者指针使用 CPU 支持的整数自增,无需加锁并且速度很快。Java 的实现在 Unsafe package 中。

消费者的等待策略

名称
措施
适用场景

BlockingWaitStrategy

加锁

CPU 资源紧缺,吞吐量和延迟并不重要的场景

BusySpinWaitStrategy

自旋

通过不断重试,减少切换线程导致的系统调用,而降低延迟。推荐在线程绑定到固定的 CPU 的场景下使用

PhasedBackoffWaitStrategy

自旋 + yield + 自定义策略

CPU 资源紧缺,吞吐量和延迟并不重要的场景

SleepingWaitStrategy

自旋 + yield + sleep

性能和 CPU 资源之间有很好的折中。延迟不均匀

TimeoutBlockingWaitStrategy

加锁,有超时限制

CPU 资源紧缺,吞吐量和延迟并不重要的场景

YieldingWaitStrategy

自旋 + yield + 自旋

性能和 CPU 资源之间有很好的折中。延迟比较均匀

名称
适用场景

BlockingWaitStrategy

CPU 资源紧缺,吞吐量和延迟并不重要的场景

BusySpinWaitStrategy

通过不断重试,减少切换线程导致的系统调用,而降低延迟。推荐在线程绑定到固定的 CPU 的场景下使用

PhasedBackoffWaitStrategy

CPU 资源紧缺,吞吐量和延迟并不重要的场景

SleepingWaitStrategy

性能和 CPU 资源之间有很好的折中。延迟不均匀

TimeoutBlockingWaitStrategy

CPU 资源紧缺,吞吐量和延迟并不重要的场景

YieldingWaitStrategy

性能和 CPU 资源之间有很好的折中。延迟比较均匀

食用方式

引入依赖

命令字和数据包

轮询策略

生成者和消费者

构造工厂

disruptor.buffer.size 这里设置为 1024 * 1024 即 1048576。

  • eventFactory:在环形缓冲区中创建事件的 factory;

  • ringBufferSize:环形缓冲区的大小,必须是 2 的幂;

  • threadFactory:用于为处理器创建线程;

  • producerType:生成器类型以支持使用正确的 sequencerpublisher 创建 RingBuffer;枚举类型,SINGLEMULTI 两个项。对应于 SingleProducerSequencerMultiProducerSequencer 两种 Sequencer

  • waitStrategy:等待策略;

启动

测试消息生产消费

一些方案

规避数据覆盖

使用 Disruptor,首先需要构建一个 RingBuffer,并指定一个大小,注意如果 RingBuffer 里面数据超过了这个大小则会覆盖旧数据。这可能是一个风险,但 Disruptor 提供了检查 RingBuffer 是否写满的机制用于规避这个问题。

Bless Bless!

参考文章: 高性能队列 Disruptor 的使用 蚂蚁金服分布式链路跟踪组件 SOFATracer 中 Disruptor 实践

最后更新于

这有帮助吗?