Flume事务
- 在Flume中一共有两个事务
·Put事务:在Source组件和Channel组件之间,保证Source组件到Channel组件之间数据传递的可靠性。
·take事务:在Channel组件和Sink组件之间,保证channel组件到Sink组件之间数据传输的可靠性。 - Put事务流程
① source组件采集外部数据到agent内部,并且将数据包装为事件
② source组件开始将事件传输到Channel组件中
③ 首先,会开启事务,在事务内部,通过doPut方法将一批数据放入到putlist中存储。
④ 之后,调用doCommit方法,把putList中的所有Event放到Channel中,成功之后就清空putList
- putList在像channel中发送数据前会先检查channel中的容量是否放得下,放不下一个都不会放,调用doRollback
- 调用doRollback方法后,doRollback方法会进行两步操作: ·将putList清空 ·抛出ChannelException异常。
- source组件会捕捉到doRollback抛出的异常后,source就将刚才的一批数据重新采集,然后就开启一个新的事务。
- 数据批的大小取决于Source组件的配置参数batch size的值
- putList的大小取决于Channel组件的配置参数transactionCapacity的值(capacity参数是指Channel的容量)
思考:put事务能否保证采集数据不丢失?
3. Take事务流程
① Sink组件不断的轮询Channel,当其中有新的事件到达时,开启take事务
② take事务开启后,会调用doTake方法将Channel组件中的Event剪切到takeList中。
③ 当takeList中存放了batch size数量的Event之后,就会调用doCommit方法
④ doCommit方法中,首先会将数据写出到外部系统,成功后就会清空takeList。
⑤ 当事务失败时,就会调用doRollback方法来进行回滚,就是将takeList中的数据原封不动的还给channel。
当take事务失败时,可能向外部写了一半的数据了,但是回滚时,是将tabkeList中的全部数返给channel,当开启新的take事务时,又会将这批数据再次写出到外部,就造成了数据重复。
思考:take事务可能造成数据重复,如何避免呢?
Flume Agent内部原理
- 执行流程
① Source组件采集外部数据到agent内部,并包装为Event
② 然后,将事件发送到ChannelProcessor中,
·通过拦截器链中每个拦截器的拦截过滤,符合要求的Event会返回到ChannelProcessor中
·在通过ChannelSelector,根据不同的选择器来决定Event去往哪个Channel,然后返回到ChannelProcessor
③ 开启Put事务,将批量的Event发送到Channel中
④ 更具SinkProcessor组件配置的类型不同,实现相应的功能(负载均衡或故障转移),最终都会且同一时刻只能有一个Sink去拉取数据。
⑤ Sink组件不断的轮询Channel,当有新的Event到达Channel时,向外部系统写出。