`
wu.sheng
  • 浏览: 65821 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

SkyWalking子项目--DataCarrier 1.0 解读

 
阅读更多

        DataCarrier作为一款轻量级的基础库,代码结果相当简单,如果通读一下代码,30-40分钟应该就能完成明确用途,这里为了方便大家更容易使用,简要介绍一下DataCarrier类库结果和使用方法。

        官方的使用文档,使用英文发布在项目主页上(https://github.com/wu-sheng/DataCarrier),大家可以直接查看,并提供了相关的实例。本篇文章主要介绍各参数的含义,底层模型,以及如何使用。

        一. DataCarrier的核心原理

        DataCarrier使用多个定长的内存数组。每个定长数组内部使用循环覆盖写入模式,在每个数组内部使用一个基于乐观锁的循环自增索引,处理写入位置,能保证写入的唯一性。在写入层面上,数据是有序循环写入的(如果策略允许不阻塞的话)。

        我们利用下图能够明确说明DataCarrier两个关键参数channelSize和bufferSize


        channelSize的大小,控制的通道数量,在合理的分区选择函数的基础上,不会出现竞争。

        bufferSize为每一个channelSize的大小,可以控制循环写入和批量消费。

        对kafka有一定了解的同学,对这两个参数的模式一定不陌生。适当的调配这两个参数,对于提高消费效率,是十分重要的。
         

        二. 分区选择器,Partitioner

        分区函数的概念同样类似kafka,当出现并行写入数据的时候,由分区函数来确认,将数据写入哪个分区,借分区函数,来有效降低并发串行写入压力,可以大幅提高效率,降低锁竞争。

        DataCarrier在1.0版本中提供了两个分区选择器

        1. ProducerThreadPartitioner<T>,根据线程id进行选择,由产生数据的写成id决定,相同的线程号,一定写入同一个分区中。

        2. SimpleRollingPartitioner <T>,简单循环自增选择器,使用无锁整形的自增,顺序选择线程号,在高负载时,会产生批量连续写入一个分区的效果,在中等负载情况下,提供较好性能。

       分区器只需要实现一个简单的分区函数

int partition(int total, T data)
       分区返回 [0, total)间的值,用于寻址分析。建议使用简单逻辑,实现快速的分区操作。

 

  

       三. 缓冲池策略

       根据缓冲池循环队列模型,数据时持续循环写入的,DataCarrier针对写满而没有来得及消费时,提供了三种默认策略。

        1. BLOCKING(默认),写入线程阻塞等待,直到数据被消费为止

        2. OVERRIDE,复写旧数据,旧数据被丢弃

        3. IF_POSSIBLE,如果无法写入则直接返回false,由应用程序判断如何处理

        缓冲池策略,对于针对不同场景,数据的高效处理,有显著意义。

 

        四. 消费者

        DataCarrier支持配置多个消费者实例,利用多线程进行并行消费。

public DataCarrier consume(IConsumer<T> prototype, int num, boolean usePrototypeCopies) 
       
         1. 参数一:自定义的消费者实例,只需要使用简单的消费者接口。数据使用批量消费模式。
public interface IConsumer<T> {
    void consume(List<T> data);

    void onError(List<T> data, Throwable t);
}
       
         2. 参数二:消费者实例数量,即同时有多少个消费线程在工作。

 

         3. 参数三:是否使用消费者实例的拷贝模式。如果使用拷贝,将会通过反射构建多个参数一类型的消费者,每个消费线程独享一个消费者,此时可以使用成员变量保持消费过程中的上下文。

             注意:此构造使用默认构造函数,无法构造的对象,依然使用参数一对象实例,不会报错。

 

         消费者数量和channel数量不一定需要对应,DataCarrier会根据数量对应关系自主尽可能平均分配

         1. 如果消费者数量 > channel数量,则每个消费者监控多条channel

         2. 如果消费者数量 < channel数量,则一个channel均分成n段,由不同的消费者监控

 

        五. 退出

        DataCarrier支持创建多个实例,也支持优雅退出。可以调用关闭方法

public void shutdownConsumers()

         DataCarrier将会关闭所有的消费线程。注意,此时不会使用立即关闭,会等待本次消费结束后退出,防止对应用程序产生不可预计的影响。

        

 

  • 大小: 55.3 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics