flume到底會丟數據嗎?其可靠性如何?——輕鬆搞懂Flume事務機制

先給出答案:網絡

須要結合具體使用的source、channel和sink來分析,具體結果可看本文最後一節code

Flume事務

  一提到事務,咱們首先就想到的是MySQL中的事務,事務就是將一批操做作成原子性的,即這一批要麼都成功,要麼都失敗。對象

  一樣的道理,在flume中也有事務,那麼Flume中的事務在哪一個地方呢?在Flume中的批量操做又是指什麼呢?blog

  • Flume中的事務存在於哪一個位置?

  在Flume中一共有兩個事務,一個是在Source到Channel之間,一個是Channel到Sink之間。在Source到Channel之間的叫put事務,在Channel到Sink之間的叫Take事務事務

  • 在Flume中兩個事務的批量操做指的是什麼?

  從source到channel過程當中,數據在flume中會被封裝成Event對象,也就是一批event,把這批event放到一個事務中,把這個事務也就是這批event一次性的放入channel中。同理,Take事務的時候,也是把這一批event組成的事務統一拿出來到sink放到HDFS上。ip

  接下來咱們看下這兩個事務具體是怎麼實現的:ci

一、Flume的Put事務

  事務確定有的兩個特性就是:成功了提交,失敗了回滾。it

  咱們先考慮Put事務的正常的狀況,即任務成功狀況。io

如圖所示:event

  事務開始的時候會調用一個doPut方法,doPut方法將一批數據(多個event)batch data 放在putList中,而這批數據「批」的大小取決於配置的 batch size 的參數的值。而putList的大小取決於配置channel的參數transaction capacity的大小,這個參數的大小就體如今putList上了。(tips:channel的另外一個參數capacity指的是channel的容量)。

如今這批數據順利的放到putList以後,接下來能夠調用doCommit方法,把putList中全部的event放到channel中,成功放完以後就清空putList

  以上是順利的狀況下,那若是事務進行的過程當中出問題了怎麼解決呢?

第一種問題:數據傳輸到channel過程出問題
  在doCommit提交以後,事務在向channel放的過程當中,事務容易出問題。好比:sink那邊取數據慢,而source這邊放數據速度快,就容易形成channel中的數據的積壓,這個時候就會形成putList中的數據放不進去。那如今事務出問題了,如何解決呢?

  經過調用doRollback方法,doRollback方法會進行兩項操做:一、將putList清空; 二、拋出channelException異常。這個時候source就會捕捉到doRollback拋出的異常,而後source就會把剛纔的一批數據從新採集一下,採集完以後從新走事務的流程。這就是事務的回滾
(putList的數據在向channel發送以前先檢查一下channel的容量可否放得下,若是放不下,就一個都不放。)

第二種問題:數據採集過程出問題
  有這麼種場景,source採集數據時候採用的是tailDir source,而咱們由於某種緣由將監控的目錄文件刪除,這個時候就會出現問題,一樣地,出現問題的解決方式是調用doRollback方法來對事務進行回滾。

二、Flume的Take事務

  Take事務和Put事務很類似。

一樣地,咱們先不考慮doRollback,先考慮順利不出問題的狀況下事務的完成。

如圖所示:

  Take事務一樣也有takeList,HDFS sink配置也有一個 batch size,這個參數決定sink從channel取數據的時候一次取多少個,因此這batch size 得小於takeList的大小,而takeList的大小取決於transaction capacity的大小,一樣是channel 中的參數。

Take事務流程:事務開始後,doTake方法會將channel中的event剪切到takeList中,固然,後面接的是HDFS Sink的話,在把channel中的event剪切到takeList中的同時也往寫入HDFS的IO緩衝流中放一份event(數據寫入HDFS是先寫入IO緩衝流而後flush到HDFS)。

  當takeList中存放了batch size 數量的event以後,就會調用doCommit方法,doCommit方法會作兩個操做:一、針對HDFS Sink,手動調用IO流的flush方法,將IO流緩衝區的數據寫入到HDFS磁盤中;二、而後直接清空takeList中的數據。

  以上是順利的狀況下,那若是事務進行的過程當中出問題了怎麼解決呢?

何時最容易出問題呢?——flush到HDFS的時候組容易出問題

  如:flush到HDFS的時候,可能因爲網絡緣由超時致使數據傳輸失敗,這個時候一樣地調用doRollback方法來進行回滾,回滾的時候,因爲takeList中還有備份數據,因此將takeList中的數據原封不動地還給channel,這時候就完成了事務的回滾。

  可是,若是flush到HDFS的時候,數據flush了一半以後出問題了,這意味着已經有一半的數據已經發送到HDFS上面了,如今出了問題,一樣須要調用doRollback方法來進行回滾,回滾並無「一半」之說,它只會把整個takeList中的數據返回給channel,而後繼續進行數據的讀寫。這樣開啓下一個事務的時候就容易形成數據重複的問題。

  因此,在某種程度上,flume對數據進行採集傳輸的時候,它有可能會形成數據的重複,可是其數據不丟失

三、flume傳輸是否會丟失或重複數據?

  這個問題須要分狀況來看,須要結合具體使用的source、channel和sink來分析。

  首先,分析source:

  (1)exec source ,後面接 tail -f ,這個數據也是有可能丟的。
  (2)TailDir source ,這個是不會丟數據的,它能夠保證數據不丟失。

  其次,分析sink:

  (1)hdfs sink,數據有可能重複,可是不會丟失。

通常生產過程當中,都是使用 **TailDir source **和 HDFS sink,因此數據會重複可是不會丟失。

  最後,分析channel   要想數據不丟失的話,仍是要用 File channel,而memory channel 在flume掛掉的時候仍是有可能形成數據的丟失的。

相關文章
相關標籤/搜索