1.lmax-Disruptor队列介绍
disruptor是英国著名的金融交易所lmax旗下技术团队开发的一款java实现的高性能内存队列框架
其发明disruptor的主要目的是为了改进传统的内存队列实现如jdk的ArrayBlockingQueue、LinkedBlockingQueue等在现代CPU硬件上的一些缺陷
1. 伪共享问题
现代的CPU都是多核的,每个核心都拥有独立的高速缓存。高速缓存由固定大小的缓存行组成(通常为32个字节或64个字节)。
CPU以缓存行作为最小单位读写,且一个缓存行通常会被多个变量占据(例如32位的引用指针占4字节,64位的引用指针占8个字节)。
这种设计导致了一个问题:即使高速缓存线上的变量不相关(例如,它们不属于同一对象),只要高速缓存线上的共享变量发生变化,整个高速缓存线就与高速缓存一致性同步。
[En]
This design leads to a problem: even if the variables on the cache line are unrelated (for example, they do not belong to the same object), as long as a shared variable on the cache line changes, the entire cache line is synchronized with cache consistency.
而CPU间缓存一致性的同步是有一定性能损耗的,能避免则尽量避免。这就是所谓的" 伪共享"问题。
disruptor通过对队列中一些关键变量进行了缓存行的填充,避免其因为不相干的变量读写而无谓的刷新缓存,解决了伪共享的问题。
关于CPU间缓存一致性相关的内容可以参考下我以前的博客:高速缓存一致性协议MESI与内存屏障
2. 队头、队尾引用等共享变量过多的的争抢
传统的内存队列由于生产者、消费者都会并发的读写队列头、队列尾的引用和更新队列size,
因此被迫使用了如ReentrantLock等基于上下文切换的悲观锁或是CAS机制的乐观锁等互斥机制来保证队列关键数据的并发安全,但即使是CAS这样非阻塞的机制,由于存在失败重试机制和高速缓存间强一致地同步操作,其性能损耗在追求极限性能的高并发队列中间件上也是不容忽视的。
disruptor在实现过程中巧妙的通过全局有序增长的序列号机制代替了显式的队列头、队列尾更新,极大的减少了需要并发更新共享变量的场合,从而提高了高并发场景下队列的吞吐量。