Flume事务和内部原理
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
public void processEvent(Event event) {
event = this.interceptorChain.intercept(event); // 提交到拦截器链 if (event == null) {
return; }
List requiredChannels = this.selector.getRequiredChannels(event); // 提交到channel 选择器 for (Iterator localIterator = requiredChannels.iterator(); localIterator.hasNext(); ) { reqChannel = (Channel)localIterator.next();
1.1 put事务
从source到channel过程中,数据在flume中会被封装成Event对象,多个event被放到一个事务中, 然后把这个包含events的事务放到channel中。
1.事务开始的时候会调用一个doPut方法,doPut方法的会将这批数据batch data,也就是一批event放到putList中。 doPut传递的数据的大小可以通过参数bathchSize配置。 putList的大小则通过channel的参数transactionCapacity进行配置。 2 当数据成功存放到putList之后,调用doCommit()方法,putList中所有的event进入channel()中, - 1)成功则清空putList. - 2) 不成功的情况 - 从putList传输到channel过程出问题,在doCommit提交之后,事务在向channel放的过程中,遇到问题。 sink那边取数据速度要比Source这边放数据速度慢,导致channel中的数据积压,这个时候就会造成putList中的数据放不进去。 这时会进行事务的回滚操作,调用doRollback方法,doRollback方法会做两个事情: - 1、清空putList中的数据; - 2、抛出channelException异常。 当source捕捉到doRollback抛出的异常,就会把刚才的一批数据重新采集一下,采集完之后重新走事务的流程。 - 在数据采集的过程中也有可能出现问题,同样是调用doRollback方法来对事务进行回滚。
2.Flume内 部 原 理
1). Source采集数据 EventBuilder.withBody(body)将数据封装成Event对象, getChannelProcessor().processEvent(event)将数据交给Channel Processor
通过源码可以看到,以avro source为例
public Void append(AvroFlumeOGEvent evt) throws AvroRemoteException {
.....
Event event = EventBuilder.withBody(evt.getBody().array(), headers); // 将数据封装成Event对象, try {
LOG.error("Error while writing to required channel: " + reqChannel, t); throw ((Error)t); }if ((t instanceof ChannelException)) { throw ((ChannelException)t); } throw new ChannelException("Unable to put event on required channel: " + reqChannel, t); } finally { if (tx != null) tx.close(); } } Channel reqChannel; List optionalChannels = this.selector.getOptionalChannels(event); for (Channel optChannel : optionalChannels) { Transaction tx = null; try { tx = optChannel.getTransaction(); tx.begin();
public ChannelProcessor(ChannelSelector selector) {
this.selector = selector; this.interceptorChain = new InterceptorChain(); }
然后在processEvent和processEventBatch(List events)
optChannel.put(event); // 将event事件写入channel
mit(); } catch (Throwable t) {
tx.rollback(); LOG.error("Unable to put event on optional channel: " + optChannel, t); if ((t instanceof Error))
Transaction tx = reqChannel.getTransaction(); Preconditions.checkNotNull(tx, "Transaction object must not be null"); try {
tx.begin(); reqChannel.put(event); mit(); } catch (Throwable t) { tx.rollback(); if ((t instanceof Error)) {
this.counterGroup.incrementAndGet(ll; }
2)Channel Processor将Event事件传递给拦截器链interceptorChain.intercept(event),然后将数据返回给Channel Processor。 3)Channel Processor将拦截过滤之后的Event事件传递给Channel选择器(Channel Selector)),Channel Selector返回给Channel Processor写入event事件的Channel列表 其中Channel Selectors有两种类型: - 1.Replicating Channel Selector : 将source过来的events发往所有的channel(相当于复制多份,默认使用的channel selector) - 2.Multiplexing Channel Selector:可以指定source发过来的events发往的channel 4)Channel Processor根据Channel选择器的选择结果,将Event事件写入相应的Channel 看下channel Processor源码 首先构造器中直接定义了selector和拦截器interceptorChain
调用dorollback方法来进行回滚takelist中还有备份数据所以将takelist中的数据原封不动地还给channel这时候就完成了事务的回滚
Flume事 务 和 内 部 原 理 1.Flume 事务
Flume使用两个独立的事务分别负责从soucrce到channel,以及从channel到sink的事件传递。 在Source到Channel之间的叫put事务,在Channel到Sink之间的叫Take事务。 事务两个特性就是:成功了提交,失败了回滚。
getChannelProcessor().processEvent(event); // 将数据交给Channel Processor this.counterGroup.incrementAndGet("rpc.events"); } catch (ChannelException ex) { return null; }
throw ((Error)t); } finally {
if (tx != null) tx.close();
} } } }
。
5)SinkProcessor启动sink,sink在channel中去轮询,取出channel中的event事件。 SinkProcessor有三种, - DefaultSinkProcessor(默认的,内部无任何逻辑,只是单纯的调用sink)、 - LoadBalancingSinkProcessor(负载均衡)、 - FaioverSinkProcessor(容灾恢复)
1.2 take事务
1.事务开始时,调用doTake方法,将channel中的event提取到(剪切)takeList中, 2.如果后面的sink是HDFS Sink,同时在写入HDFS的IO缓冲流中放一份event。 3.当takeList中存放的Event达到约定数量(batchSize) ,就会调用doCommit方法: - 成功执行情况下: - 如果是HDFS Sink,那么手动调用IO流的flush方法,将IO流缓冲区的数据写入到HDFS磁盘中,同时清空takeList中的数据 - 失败情况下: - 1.网络延迟等原因导致传输数据失败, 调用doRollback方法来进行回滚,takeList中还有备份数据,所以将takeList中的数据原封不动地还给channel,这时候就完成了事务的回滚。 - 2.如果takeList数据有一部分传输成功了,剩下的因为网络延迟传输失败了。 同样会调用doRollback方法来进行回滚,它会把整个takeList中的数据返回给channel,然后继续进行数据的读写。 如此一来,再次进行事务时候,就会存在数据重复的可能。
event = this.interceptorChain.intercept(event); // 提交到拦截器链 if (event == null) {
return; }
List requiredChannels = this.selector.getRequiredChannels(event); // 提交到channel 选择器 for (Iterator localIterator = requiredChannels.iterator(); localIterator.hasNext(); ) { reqChannel = (Channel)localIterator.next();
1.1 put事务
从source到channel过程中,数据在flume中会被封装成Event对象,多个event被放到一个事务中, 然后把这个包含events的事务放到channel中。
1.事务开始的时候会调用一个doPut方法,doPut方法的会将这批数据batch data,也就是一批event放到putList中。 doPut传递的数据的大小可以通过参数bathchSize配置。 putList的大小则通过channel的参数transactionCapacity进行配置。 2 当数据成功存放到putList之后,调用doCommit()方法,putList中所有的event进入channel()中, - 1)成功则清空putList. - 2) 不成功的情况 - 从putList传输到channel过程出问题,在doCommit提交之后,事务在向channel放的过程中,遇到问题。 sink那边取数据速度要比Source这边放数据速度慢,导致channel中的数据积压,这个时候就会造成putList中的数据放不进去。 这时会进行事务的回滚操作,调用doRollback方法,doRollback方法会做两个事情: - 1、清空putList中的数据; - 2、抛出channelException异常。 当source捕捉到doRollback抛出的异常,就会把刚才的一批数据重新采集一下,采集完之后重新走事务的流程。 - 在数据采集的过程中也有可能出现问题,同样是调用doRollback方法来对事务进行回滚。
2.Flume内 部 原 理
1). Source采集数据 EventBuilder.withBody(body)将数据封装成Event对象, getChannelProcessor().processEvent(event)将数据交给Channel Processor
通过源码可以看到,以avro source为例
public Void append(AvroFlumeOGEvent evt) throws AvroRemoteException {
.....
Event event = EventBuilder.withBody(evt.getBody().array(), headers); // 将数据封装成Event对象, try {
LOG.error("Error while writing to required channel: " + reqChannel, t); throw ((Error)t); }if ((t instanceof ChannelException)) { throw ((ChannelException)t); } throw new ChannelException("Unable to put event on required channel: " + reqChannel, t); } finally { if (tx != null) tx.close(); } } Channel reqChannel; List optionalChannels = this.selector.getOptionalChannels(event); for (Channel optChannel : optionalChannels) { Transaction tx = null; try { tx = optChannel.getTransaction(); tx.begin();
public ChannelProcessor(ChannelSelector selector) {
this.selector = selector; this.interceptorChain = new InterceptorChain(); }
然后在processEvent和processEventBatch(List events)
optChannel.put(event); // 将event事件写入channel
mit(); } catch (Throwable t) {
tx.rollback(); LOG.error("Unable to put event on optional channel: " + optChannel, t); if ((t instanceof Error))
Transaction tx = reqChannel.getTransaction(); Preconditions.checkNotNull(tx, "Transaction object must not be null"); try {
tx.begin(); reqChannel.put(event); mit(); } catch (Throwable t) { tx.rollback(); if ((t instanceof Error)) {
this.counterGroup.incrementAndGet(ll; }
2)Channel Processor将Event事件传递给拦截器链interceptorChain.intercept(event),然后将数据返回给Channel Processor。 3)Channel Processor将拦截过滤之后的Event事件传递给Channel选择器(Channel Selector)),Channel Selector返回给Channel Processor写入event事件的Channel列表 其中Channel Selectors有两种类型: - 1.Replicating Channel Selector : 将source过来的events发往所有的channel(相当于复制多份,默认使用的channel selector) - 2.Multiplexing Channel Selector:可以指定source发过来的events发往的channel 4)Channel Processor根据Channel选择器的选择结果,将Event事件写入相应的Channel 看下channel Processor源码 首先构造器中直接定义了selector和拦截器interceptorChain
调用dorollback方法来进行回滚takelist中还有备份数据所以将takelist中的数据原封不动地还给channel这时候就完成了事务的回滚
Flume事 务 和 内 部 原 理 1.Flume 事务
Flume使用两个独立的事务分别负责从soucrce到channel,以及从channel到sink的事件传递。 在Source到Channel之间的叫put事务,在Channel到Sink之间的叫Take事务。 事务两个特性就是:成功了提交,失败了回滚。
getChannelProcessor().processEvent(event); // 将数据交给Channel Processor this.counterGroup.incrementAndGet("rpc.events"); } catch (ChannelException ex) { return null; }
throw ((Error)t); } finally {
if (tx != null) tx.close();
} } } }
。
5)SinkProcessor启动sink,sink在channel中去轮询,取出channel中的event事件。 SinkProcessor有三种, - DefaultSinkProcessor(默认的,内部无任何逻辑,只是单纯的调用sink)、 - LoadBalancingSinkProcessor(负载均衡)、 - FaioverSinkProcessor(容灾恢复)
1.2 take事务
1.事务开始时,调用doTake方法,将channel中的event提取到(剪切)takeList中, 2.如果后面的sink是HDFS Sink,同时在写入HDFS的IO缓冲流中放一份event。 3.当takeList中存放的Event达到约定数量(batchSize) ,就会调用doCommit方法: - 成功执行情况下: - 如果是HDFS Sink,那么手动调用IO流的flush方法,将IO流缓冲区的数据写入到HDFS磁盘中,同时清空takeList中的数据 - 失败情况下: - 1.网络延迟等原因导致传输数据失败, 调用doRollback方法来进行回滚,takeList中还有备份数据,所以将takeList中的数据原封不动地还给channel,这时候就完成了事务的回滚。 - 2.如果takeList数据有一部分传输成功了,剩下的因为网络延迟传输失败了。 同样会调用doRollback方法来进行回滚,它会把整个takeList中的数据返回给channel,然后继续进行数据的读写。 如此一来,再次进行事务时候,就会存在数据重复的可能。