并发编程框架Disruptor之高性能设计

举报
JavaEdge 发表于 2021/06/04 00:08:47 2021/06/04
【摘要】 架构 UML 1 单线程写 Disruptor的RingBuffer, 之所以可以做到完全无锁,也是因为"单线程写",这是所有"前提的前提",离了这个前提条件,没有任何技术可以做到完全无锁。Redis、Netty等等高性能技术框架的设计都是这个核心思想。 2 系统内存优化-内存屏障 要正确的实现无锁,还需要另外一个关键技术:内存屏障。对应到Java语言,就是...

架构 UML

1 单线程写

Disruptor的RingBuffer, 之所以可以做到完全无锁,也是因为"单线程写",这是所有"前提的前提",离了这个前提条件,没有任何技术可以做到完全无锁。Redis、Netty等等高性能技术框架的设计都是这个核心思想。

2 系统内存优化-内存屏障

要正确的实现无锁,还需要另外一个关键技术:内存屏障。对应到Java语言,就是valotile变量与happens before语义。

参阅: 内存屏障 - Linux的smp_wmb()/smp_ rmb()
系统内核:比如Linux的kfifo:smp_ wmb(),无论是底层的读写
都是使用了Linux的smp_ wmb
https://github.com/opennetworklinux/linux-3.8.13/blob/master/kernel/kfifo.c

3 系统缓存优化-消除伪共享

缓存系统中是以缓存行(cache line) 为单位存储的。缓存行是2的整数幂个连续字节,一般为32-256个字节。最常见的缓存行大小是64个字节。

当多线程修改互相独立的变量时,如果这些变量共享同一个缓存行,就会无意中影响彼此的性能,这就是伪共享。

核心:Sequence

可看成是一个AtomicLong用于标识进度。还有另外一个目的就是防止不同Sequence之间CPU缓存伪共享(Flase Sharing)的问题。

  • 如下设计保证我们保存的 value 永远在一个缓存行中。(8 个long,正好 64 字节)。这也是一个空间换时间的案例。

4 算法优化-序号栅栏机制

我们在生产者进行投递Event的时候,总是会使用:

long sequence = ringBuffer.next();

  
 
  • 1

Disruptor3.0中,序号栅栏SequenceBarrier和序号Sequence搭配使用。协调和管理消费者与生产者的工作节奏,避免了锁和CAS的使用。

  • 消费者序号数值必须小于生产者序号数值
  • 消费者序号数值必须小于其前置(依赖关系)消费者的序号数值
  • 生产者序号数值不能大于消费者中最小的序号数值
  • 以避免生产者速度过快,将还未来得及消费的消息覆盖

SingleProducerSequencerPad#next

 /** * @see Sequencer#next(int) */ @Override public long next(int n) // 1 { if (n < 1) // 初始值:sequence = -1 { throw new IllegalArgumentException("n must be > 0"); }
		// 语义级别的
		// nextValue为SingleProducerSequencer的变量 long nextValue = this.nextValue; long nextSequence = nextValue + n; // 用于判断当前序号是否绕过整个 ringbuffer 容器 long wrapPoint = nextSequence - bufferSize; // 用于缓存优化 long cachedGatingSequence = this.cachedValue; if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue) { long minSequence; while (wrapPoint > (minSequence = Util.getMinimumSequence(gatingSequences, nextValue))) { LockSupport.parkNanos(1L); // TODO: Use waitStrategy to spin? } this.cachedValue = minSequence; } this.nextValue = nextSequence; return nextSequence; }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

参考

  • https://zhuanlan.zhihu.com/p/21355046

文章来源: javaedge.blog.csdn.net,作者:JavaEdge.,版权归原作者所有,如需转载,请联系作者。

原文链接:javaedge.blog.csdn.net/article/details/108935684

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。