天天看點

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont

說明:翻譯在盡量符合原文表達的基礎上,盡量保證行文流暢。水準有限,請多指正! 這篇文章是關于Flume FileChannel的。Flume是為高效收集聚合大量日志資料設計的可靠的、可用的分布式系統。它有一個基于流式資料流的簡單靈活的體系。它提供了可控的可靠機制和許多故障轉移與恢複機制。它使用了一個用于線上分析應用的簡單可擴充的資料模型。
FileChannel是一個持久化的Flume channel,支援并行的寫到多個磁盤并且支援加密。

概念

        當使用Flume時,每個流程都有一個Source、Channel、Sink。一個典型的例子是一個webserver通過RPC(比如:AvroSource)将events寫到一個Source、然後Source将events寫到MemoryChannel,最後HDFSSink消費event,将它寫到HDFS。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
       MemoryChannel能提供很高的吞吐量,但是當系統斷電或程式崩潰時會丢失資料。是以人們急需一個能持久化的Channel。FileChannel在FLUME-1085被實作。它的目标是提供一個可靠的高吞吐量的Channel。FileChannel保證當斷電或崩潰發生時,事務被送出,沒有資料丢失。        重要的一點是FileChannel不做任何資料的複制,僅依賴于底層磁盤的可靠性,是以,由于持久性需要使用FileChannel的使用者在購買和配置硬體時注意這一點。底層的磁盤将要做RAID、SAN或類似的東西。        許多系統為了高的吞吐率需要拿允許小量資料丢失做交換。Flume組決定FileChannel采用不同的方式。Flume是一個支援事務的系統,多個event可以在單個事務中被put或take。batch size用來控制吞吐率。使用大的batch size,flume可以以高吞吐率移動資料,并且不丢失資料。batch size完全可以通過client控制。這個方法與DBMS 相似。        一個flume事務包含put或take,一個事務中不能同時有put和take操作。每個事務都要實作put和take方法。source通過put将event放入channel,sink通過take将event從channel拿走。

設計

       FileChannel是基于記憶體隊列和WAL設計的。每次事務都是根據事物類型(Take和Put)寫到WAL,隊列也做相應的修改。每次事務被commited,都會調用fsync確定events被存儲在磁盤檔案,同時指向該event的指針被放到隊列中。這裡的隊列服務就像其他隊列一樣:它管理着什麼被sink消費。在Take期間,該event的指針從隊列被删除。直接從WAL讀這個event。由于今天我們有大量可用的RAM,從作業系統的檔案緩存中讀取也是經常發生的。        崩潰後,通過重放WALs,隊列位置能恢複到崩潰前同樣的狀态,而那些沒有commited的事務被丢棄。重放WALs相當耗時,是以隊列本身會周期性的寫到磁盤。将隊列寫到磁盤稱為checkpoint。這樣,崩潰後,隊列首先從磁盤checkpoint檔案加載,然後僅僅重放那些隊列被最後一次checkpoint到磁盤後commited的事務,這樣明顯的減少了讀取WAL的數量。        例如,一個channel有2個event,如下所示:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
       WALs包含3個重要的屬性:事務ID、序列号、event資料。每個事務都有唯一的事務Id,并且每個event都有唯一的序列号。事務Id被用來簡單的将event分組到同一事務,而序列号在重放log時使用。上圖中,事務ID為1,序列号為1,2,3.       當隊列被checkpoint到磁盤,增加序列号,同時序列号也被儲存到磁盤。重新開機時,隊列首先從磁盤加載,然後比隊列序列号大的任何WAL實體被重放。checkpoin操作期間,隊列是locked,以至于沒有Put或Take操作可以更改它的狀态。如果checkpoint期間允許隊列的修改,将導緻磁盤存儲的隊列快照與實際隊列不一緻。        在上面例子中,事務1commited後,checkpoint發生,在隊列中的結果帶着events被儲存到磁盤還有序列号4也被儲存。        之後,在事務2中,從隊列take一個event:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
        如果這個時候崩潰了,重新開機時隊列從checkpoint加載,注意,checkpoint發生在事務2前,2個event“a”和“b”都會被加載到隊列,之後任何比4大的已經确認的事務被重放,重放後,“a”event從隊列被删除。
       上面的設計2點沒有考慮到,Take或Put進行中,同時發生checkpoint,會導緻資料丢失。假定checkpoint發生在take“a”之後:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
        如果此時崩潰,在以上描述的設計下,event“b”被加載進入隊列,之後重放比5大的任何WAL實體,事務2被rollback,但是這裡的take “a”不會被重放。event “a”被丢失,Put也存在相似的情況。由于這個原因,當隊列的checkpoint發生時,仍然在進行中的事務也被寫出,以至于可以适當的處理這個問題。

實作

       FileChannel在Flume項目的flume-file-channel子產品,對應包名為org.apache.flume.channel.file。上面描述的隊列對應FlumeEventQueue類,WAL對應Log類。隊列本身是一個環形數組,通過記憶體映射檔案支撐;而WAL對應一組檔案,可以使用LogFile類和它的子類讀寫這些檔案。

結論

       FileChannel在遇到硬體、軟體、環境失敗時,給Flume使用者提供了持久化的保證,而且具有高的吞吐量。這兩個方面對于大多數情況都是比較重要的,是以FileChannel是推薦使用的Channel。