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


先給出答案:

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

Flume事務

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

  同樣的道理,在flume中也有事務,那么Flume中的事務在哪個地方呢?在Flume中的批量操作又是指什么呢?

  • 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上。

  接下來我們看下這兩個事務具體是怎么實現的:

1、Flume的Put事務

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

  我們先考慮Put事務的正常的情況,即任務成功情況。

如圖所示:

  事務開始的時候會調用一個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方法會進行兩項操作:1、將putList清空; 2、拋出channelException異常。這個時候source就會捕捉到doRollback拋出的異常,然后source就會把剛才的一批數據重新采集一下,采集完之后重新走事務的流程。這就是事務的回滾
(putList的數據在向channel發送之前先檢查一下channel的容量能否放得下,如果放不下,就一個都不放。)

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

2、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方法會做兩個操作:1、針對HDFS Sink,手動調用IO流的flush方法,將IO流緩沖區的數據寫入到HDFS磁盤中;2、然后直接清空takeList中的數據。

  以上是順利的情況下,那如果事務進行的過程中出問題了怎么解決呢?

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

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

  但是,如果flush到HDFS的時候,數據flush了一半之后出問題了,這意味着已經有一半的數據已經發送到HDFS上面了,現在出了問題,同樣需要調用doRollback方法來進行回滾,回滾並沒有“一半”之說,它只會把整個takeList中的數據返回給channel,然后繼續進行數據的讀寫。這樣開啟下一個事務的時候就容易造成數據重復的問題。

  所以,在某種程度上,flume對數據進行采集傳輸的時候,它有可能會造成數據的重復,但是其數據不丟失

3、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掛掉的時候還是有可能造成數據的丟失的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM