flume MemoryChannel分析

前边介绍了flume的基本概念和Source部分,接下来看看flume中的第二大组件Channel中的MemoryChannel。MemoryChannel是完全在内存中运行,速度很快,其优点同样也就成了缺点,不能持久化,若机器发生宕机或断电,数据就会丢失。在实际使用中需要根据具体的需求进行合理的选择。 
先看下MemoryChannel的基本的类图,根据这个结构图可以很好的帮助理解。 
 
MemoryChannel中最重要的部分主要是Channel、Transaction 和Configurable三个接口。 
Channel接口中主要声明了Channel中的三个方法:

 
 
 
  1. public void put(Event event) throws ChannelException; //刚方法从指定的Source中获得Event放入指定的Channel中
  2. public Event take() throws ChannelException; //take方法主要是从Channel中取出event放入Sink中
  3. public Transaction getTransaction(); //getTransaction方法是获得当前Channel的事务实例

Transaction接口主要声明了flume中事务机制的四个方法:

 
 
 
  1. enum TransactionState { Started, Committed, RolledBack, Closed } //枚举类型,指定了事务的四种状态,事务开始、提交、失败回滚、关闭
  2. void begin();
  3. void commit();
  4. void rollback();
  5. void close();

Configurable接口主要是和flume配置组件相关的,需要从flume配置系统获取配置信息的任何组件,都必须实现该接口。该接口中只声明了一个context方法,用于获取配置信息。 
以上方法的具体内容都是在具体的Channel中实现的,系统在启动时会根据配置文件信息调用相应的组件的方法实现,这种实现称为回调,类似于C语言中的钩子函数,先声明方法然后在具体的需要时调用相应的实现方法。

接下来看看具体的代码实现,代码开始是定义一些默认的配置信息,Channel、Transaction事务大小等信息:

 
 
 
  1. public class MemoryChannel extends BasicChannelSemantics {
  2. private static Logger LOGGER = LoggerFactory.getLogger(MemoryChannel.class);
  3. private static final Integer defaultCapacity = 100;
  4. private static final Integer defaultTransCapacity = 100;
  5. private static final double byteCapacitySlotSize = 100;
  6. private static final Long defaultByteCapacity = (long)(Runtime.getRuntime().maxMemory() * .80);
  7. private static final Integer defaultByteCapacityBufferPercentage = 20;
  8. private static final Integer defaultKeepAlive = 3;

接下来就是实现Channel的put、get方法和事务的commit、rollback方法,这几个方法都是在内部类 MemoryTransaction 实现的,看到下边的几个方法名字,大家可能会问怎么每个方法前边都有个do,实际上这是因为 MemoryTransaction 继承了BasicTransactionSemantics抽象类,而不是直接实现了 Channel 和 Transaction 接口,在 BasicTransactionSemantics抽象接口中 对上边提到的几种方法做了一些简单的封装,在内部调用就是调用类似doTake的方法:

 
 
 
  1. protected Event take() {
  2. Preconditions.checkState(Thread.currentThread().getId() == initialThreadId,
  3. "take() called from different thread than getTransaction()!");
  4. Preconditions.checkState(state.equals(State.OPEN),
  5. "take() called when transaction is %s!", state);
  6. try {
  7. return doTake();
  8. } catch (InterruptedException e) {
  9. Thread.currentThread().interrupt();
  10. return null;
  11. }
  12. }

具体的 MemoryTransaction 内部类实现的几个方法如下代码:

 
 
 
  1. private class MemoryTransaction extends BasicTransactionSemantics {
  2. private LinkedBlockingDeque<Event> takeList; //阻塞双端队列,从channel中取event先放入takeList,输送到sink,commit成功,从channel queue中删除
  3. private LinkedBlockingDeque<Event> putList; //从source 会先放至putList,然后commit传送到channel queue队列
  4. private final ChannelCounter channelCounter
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值