202111-25更文-环形队列disruptor

148 阅读2分钟

这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战

环形队列disruptor

前文

本文主要为disruptor环形队列使用过程中的一些个人理解,难免有不足之处,还请见谅。

disruptor介绍

disruptor主要是java的一个环形队列组件,主要特性是能够达到高性能内存队列的效果,提升系统性能。队列,顾名思义,可以很容易想到kafka等等消息队列。distuptor同样具备消息队列的特性,通过对于消息的队列化处理,实现消息消费过程中性能的提升。

disruptor的使用

生产者代码

public class LogEventProducerWithTranslator {
    private final static EventTranslatorVararg<LogEvent> translator = (logEvent, seq, objs) -> {
        logEvent.setDetailJson((DetailJson) objs[0]);
        logEvent.setMsg((String)objs[1]);
    };

    private final RingBuffer<LogEvent> ringBuffer;
    public LogEventProducerWithTranslator(RingBuffer<LogEvent> ringBuffer){
        this.ringBuffer = ringBuffer;
    }

    public void onData(DetailJson detailJson,String msg){
        this.ringBuffer.publishEvent(translator, detailJson, msg);
    }
}

消费者代码

public class LogEventConsumer implements EventHandler<LogEvent> {
    @Override
    public void onEvent(LogEvent logEvent, long l, boolean b) throws Exception {
        System.out.println("seq:" + l + ",bool:" + b + ",logEvent:" + logEvent.toString());
        });
    }
}

既然是队列,那么必要包含生产者和消费者两部分结构。如上,为简单的生产者和消费者的代码。在使用disruptor的过程中,首先应对于队列进行初始化构建。通过初始化,可以对于队列进行一些配置信息的指定,包含消费者、队列等等。再通过队列指定生产者所使用的消息队列。在使用过程中,当消息到达系统中,通过生产者将消息发送到环形队列中。消费时,直接通过消费者进行数据的处理,这样避免了瞬时可能出现的系统瓶颈,提升系统性能。

disruptor解决缓存行对其问题

除了队列本身,disruptor一个优势还是解决了缓存行对其的问题。众所周知,cpu具有三级缓存。当两个不同的数据存储在同一个缓存行中时,会导致当其中一个数据产生变化,另一个数据会由于线程之间共享的数据模型将数据写回主存,再从主存写到缓存中,导致缓存失效重新生成缓存。这样的过程会对性能有所影响。而该框架通过采用环形队列,将不同的数据固定存储在不同的缓存行中,不会出现伪共享的问题。以此方式,也达到了性能上的提升。

后记

  • 千古兴亡多少事?悠悠。不尽长江滚滚流。