海量日誌收集利器 —— Flume

Flume 是什麼?

Flume是一個分佈式、可靠、和高可用的海量日誌聚合的系統,支持在系統中定製各類數據發送方,用於收集數據;同時,Flume提供對數據進行簡單處理,並寫到各種數據接受方(可定製)的能力。

Flume 特點

1、可靠性

當節點出現故障時,日誌能夠被傳送到其他節點上而不會丟失。Flume提供了三種級別的可靠性保障,從強到弱依次分別爲:end-to-end(收到數據agent首先將event寫到磁盤上,當數據傳送成功後,再刪除;如果數據發送失敗,可以重新發送。),Store on failure(這也是scribe採用的策略,當數據接收方crash時,將數據寫到本地,待恢復後,繼續發送),Best effort(數據發送到接收方後,不會進行確認)。

2、可擴展性

Flume採用了三層架構,分別爲agent,collector和storage,每一層均可以水平擴展。其中,所有agent和collector由master統一管理,這使得系統容易監控和維護,且master允許有多個(使用ZooKeeper進行管理和負載均衡),這就避免了單點故障問題。

3、可管理性

所有agent和colletor由master統一管理,這使得系統便於維護。多master情況,Flume利用ZooKeeper和gossip,保證動態配置數據的一致性。用戶可以在master上查看各個數據源或者數據流執行情況,且可以對各個數據源配置和動態加載。Flume提供了web 和shell script command兩種形式對數據流進行管理。

4、功能可擴展性

用戶可以根據需要添加自己的agent,collector或者storage。此外,Flume自帶了很多組件,包括各種agent(file, syslog等),collector和storage(file,HDFS等)。

5、文檔豐富,社區活躍

Flume 已經成爲 Hadoop 生態系統的標配,它的文檔比較豐富,社區比較活躍,方便我們學習。

Flume OG 與 Flume NG 的對比

1、Flume OG

Flume OG:Flume original generation 即Flume 0.9.x版本,它由agent、collector、master等組件構成。

2、Flume NG

Flume NG:Flume next generation ,即Flume 1.x版本,它由Agent、Client等組件構成。

3、Flume NG版本的優點

1)相對於Flume OG版本,Flume NG版本代碼比較簡單。

2)相對於Flume OG版本,Flume NG版本架構簡潔。

接下來我們重點講解 Flume NG。

Flume NG基本架構

Flume NG是一個分佈式、可靠、可用的系統,它能夠將不同數據源的海量日誌數據進行高效收集、聚合、移動,最後存儲到一箇中心化數據存儲系統中。由原來的Flume OG到現在的Flume NG,進行了架構重構,並且現在NG版本完全不兼容原來的OG版本。經過架構重構後,Flume NG更像是一個輕量的小工具,非常簡單,容易適應各種方式日誌收集,並支持failover和負載均衡。

Flume NG 的架構圖如下所示。

Flume NG架構圖

Flume NG核心概念

Flume的架構主要有一下幾個核心概念:

1、Event:一個數據單元,帶有一個可選的消息頭。

2、Flow:Event從源點到達目的點的遷移的抽象。

3、Client:操作位於源點處的Event,將其發送到Flume Agent。

4、Agent:一個獨立的Flume進程,包含組件Source、Channel、Sink。

5、Source:用來消費傳遞到該組件的Event。

6、Channel:中轉Event的一個臨時存儲,保存有Source組件傳遞過來的Event。

7、Sink:從Channel中讀取並移除Event,將Event傳遞到Flow Pipeline中的下一個Agent(如果有的話)

下面我們分別介紹以上幾個核心的概念。

Event

1、Event 是Flume數據傳輸的基本單元。

2、Flume 以事件的形式將數據從源頭傳輸到最終的目的。

3、Event 由可選的header和載有數據的一個byte array構成。

1)載有的數據對Flume是不透明的。

2)Header 是容納了key-value字符串對的無序集合,key在集合內是唯一的。

3)Header 可以在上下文路由中使用擴展。

Client

1、Client 是一個將原始log包裝成events並且發送它們到一個或者多個agent的實體。

2、Client 在Flume的拓撲結構中不是必須的,它的目的是從數據源系統中解耦Flume

Agent

1、一個Agent包含Source、Channel、Sink和其他組件。

2、它利用這些組件將events從一個節點傳輸到另一個節點或最終目的地。

3、agent是Flume流的基礎部分。

4、Flume 爲這些組件提供了配置、生命週期管理、監控支持。

Agent之Source

1、Source負責接收event或通過特殊機制產生event,並將events批量的放到一個或多個Channel。

2、Source包含event驅動和輪詢兩種類型。

3、Source 有不同的類型。

1)與系統集成的Source:Syslog,NetCat。

2)自動生成事件的Source:Exec

3)用於Agent和Agent之間的通信的IPC Source:Avro、Thrift。

4、Source必須至少和一個Channel關聯。

Agent之Channel與Sink

Agent之Channel

1、Channel位於Source和Sink之間,用於緩存進來的event。

2、當Sink成功的將event發送到嚇一跳的Channel或最終目的地,event才Channel中移除。

3、不同的Channel提供的持久化水平也是不一樣的:

1)Memory Channel:volatile。

2)File Channel:基於WAL實現。

3)JDBC Channel:基於嵌入Database實現。

4、Channel支持事物,提供較弱的順序保證。

5、Channel可以和任何數量的Source和Sink工作。

Agent之Sink

1、Sink負責將event傳輸到嚇一跳或最終目的,成功完成後將event從Channel移除。

2、有不同類型的Sink:

1)存儲event到最終目的的終端Sink。比如HDFS,HBase。

2)自動消耗的Sink。比如:Null Sink。

3)用於Agent間通信的IPC sink:Avro。

3、Sink必須作用於一個確切的Channel。

Flume NG部署

下面我們來安裝部署 Flume NG,這裏我們安裝配置兩個節點cloud003、cloud004,以Avro Source+Memory Channel+HDFS Sink結合方式示例講解,大家下去可以嘗試其他實現方式。

1、下載flume安裝包。

apache-flume-1.6.0-bin.tar.gz安裝包分別解壓到cloud003、cloud004節點上的/usr/java/hadoop/app/目錄下。這裏我們以cloud003爲例,cloud004同樣操作。

[hadoop@cloud003 app]$ tar -zxvf apache-flume-1.6.0-bin.tar.gz	//解壓
[hadoop@cloud003 app]$ mv apache-flume-1.6.0-bin flume //修改文件名稱

2、在cloud003節點上,進入flume/conf目錄。

[hadoop@cloud003 app]$ cd flume/conf
[hadoop@cloud003 conf]$ ls
flume-conf.properties.template  flume-env.ps1.template  flume-env.sh.template  log4j.properties

需要通過flume-conf.properties.template複製一個flume-conf.properties配置文件。

[hadoop@cloud003 conf]$ cp flume-conf.properties.template flume-conf.properties
[hadoop@cloud003 conf]$ ls
flume-conf.properties flume-conf.properties.template  flume-env.ps1.template  flume-env.sh.template  log4j.properties

修改cloud003節點上的flume-conf.properties配置文件。這裏收集日誌文件到收集端。配置參數的詳細說明可以參考官方文檔

[hadoop@cloud003 conf]$ vi flume-conf.properties
#定義source、channel、sink 名稱
a1.sources  = r1 //這裏的a1命名可以自定義,但需要跟後面啓動配置名稱一致就可以
a1.sinks =  k1
a1.channels  = c1

#定義並配置r1
a1.sources.r1.channels = c1
a1.sources.r1.type = avro //source類型
a1.sources.r1.bind = 0.0.0.0 //默認綁定本機
a1.sources.r1.port=41414 //默認端口

# 定義並配置k1
a1.sinks.k1.channel = c1
a1.sinks.k1.type = avro //sink類型
a1.sinks.k1.hostname = cloud004 //將數據傳遞給cloud004
a1.sinks.k1.port = 41414 //默認端口號

#定義並配置c1
a1.channels.c1.type=FILE //channel類型

3、在cloud004節點上,進入flume/conf目錄。

[hadoop@cloud004 app]$ cd flume/conf
[hadoop@cloud004 conf]$ ls
flume-conf.properties.template  flume-env.ps1.template  flume-env.sh.template  log4j.properties

需要通過flume-conf.properties.template複製一個flume-conf.properties配置文件。

[hadoop@cloud004 conf]$ cp flume-conf.properties.template flume-conf.properties
[hadoop@cloud004 conf]$ ls
flume-conf.properties flume-conf.properties.template  flume-env.ps1.template  flume-env.sh.template  log4j.properties

修改cloud004節點上的flume-conf.properties配置文件。從cloud003端接收數據,然後寫入到HDFS文件系統中。配置參數的詳細說明可以參考官方文檔

[hadoop@cloud004 conf]$ vi flume-conf.properties
# 定義source、channel、sink 名稱
a1.sources = r1
a1.sinks = k1
a1.channels = c1

#定義並配置 r1
a1.sources.r1.type  = avro //這裏要跟cloud003端的sink類型一致
a1.sources.r1.bind  = 0.0.0.0
a1.sources.r1.port  = 41414
a1.sources.r1.channels = c1

#定義並配置k1
a1.sinks.k1.channel = c1
a1.sinks.k1.type=hdfs //sink的輸出類型爲hdfs
a1.sinks.k1.hdfs.path=hdfs://cloud001:9000/data/flume //hdfs上傳文件路徑
a1.sinks.k1.hdfs.fileType=DataStream

#定義並配置c1
a1.channels.c1.type=File

4、首先要保證 Hadoop 集羣正常運行,這裏cloud001是Namenode。

[hadoop@cloud001 hadoop]$ jps
2625 JournalNode
1563 QuorumPeerMain
18808 NameNode
26146 Jps
3583 ResourceManager

5、首先在cloud004節點上啓動Agent,保證能接受傳過來的數據,然後傳遞給hdfs。

[hadoop@cloud003 flume]$ bin/flume-ng agent -c ./conf/ -f conf/flume-conf.properties -Dflume.root.logger=INFO,console -n a1
Info: Including Hadoop libraries found via (/usr/java/hadoop/bin/hadoop) for HDFS access
Info: Excluding /usr/java/hadoop/share/hadoop/common/lib/slf4j-api-1.7.5.jar from classpath
Info: Excluding /usr/java/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.5.jar from classpath
Info: Including Hive libraries found via () for Hive access
2015-08-25 08:54:22,018 (conf-file-poller-0) [INFO - org.apache.flume.node.PollingPropertiesFileConfigurationProvider$FileWatcherRunnable.run(PollingPropertiesFileConfigurationProvider.java:133)] Reloading configuration file:conf/flume-conf.properties
2015-08-25 08:54:22,033 (conf-file-poller-0) [INFO - org.apache.flume.conf.FlumeConfiguration$AgentConfiguration.addProperty(FlumeConfiguration.java:1017)] Processing:k1
2015-08-25 08:54:22,829 (lifecycleSupervisor-1-0) [INFO - org.apache.flume.instrumentation.MonitoredCounterGroup.start(MonitoredCounterGroup.java:96)] Component type: CHANNEL, name: c1 started
2015-08-25 08:54:22,830 (conf-file-poller-0) [INFO - org.apache.flume.node.Application.startAllComponents(Application.java:173)] Starting Sink k1
2015-08-25 08:54:22,830 (conf-file-poller-0) [INFO - org.apache.flume.node.Application.startAllComponents(Application.java:184)] Starting Source r1
2015-08-25 08:54:22,832 (lifecycleSupervisor-1-4) [INFO - org.apache.flume.source.AvroSource.start(AvroSource.java:228)] Starting Avro source r1: { bindAddress: 0.0.0.0, port: 41414 }...
2015-08-25 08:54:22,835 (lifecycleSupervisor-1-1) [INFO - org.apache.flume.instrumentation.MonitoredCounterGroup.register(MonitoredCounterGroup.java:120)] Monitored counter group for type: SINK, name: k1: Successfully registered new MBean.
2015-08-25 08:54:22,835 (lifecycleSupervisor-1-1) [INFO - org.apache.flume.instrumentation.MonitoredCounterGroup.start(MonitoredCounterGroup.java:96)] Component type: SINK, name: k1 started
2015-08-25 08:54:23,326 (lifecycleSupervisor-1-4) [INFO - org.apache.flume.instrumentation.MonitoredCounterGroup.register(MonitoredCounterGroup.java:120)] Monitored counter group for type: SOURCE, name: r1: Successfully registered new MBean.
2015-08-25 08:54:23,327 (lifecycleSupervisor-1-4) [INFO - org.apache.flume.instrumentation.MonitoredCounterGroup.start(MonitoredCounterGroup.java:96)] Component type: SOURCE, name: r1 started
2015-08-25 08:54:23,328 (lifecycleSupervisor-1-4) [INFO - org.apache.flume.source.AvroSource.start(AvroSource.java:253)] Avro source r1 started.

需要注意的是:-n a1中的參數值a1必須與flume-conf.properties配置文件的a1名稱一致。

6、在cloud003節點上,啓動Avro Client,發送數據給cloud004節點的agent。

[hadoop@cloud003 flume]$ bin/flume-ng avro-client -c ./conf/ -H cloud004 -p 41414 -F /usr/java/hadoop/app/flume/mydata/2.log -Dflume.root.logger=DEBUG,console
Info: Including Hadoop libraries found via (/usr/java/hadoop/bin/hadoop) for HDFS access
Info: Excluding /usr/java/hadoop/share/hadoop/common/lib/slf4j-api-1.7.5.jar from classpath
Info: Excluding /usr/java/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.5.jar from classpath
Info: Including Hive libraries found via () for Hive access
2015-08-25 09:10:42,629 (main) [DEBUG - org.apache.flume.api.NettyAvroRpcClient.configure(NettyAvroRpcClient.java:499)] Batch size string = 5
2015-08-25 09:10:42,672 (main) [WARN - org.apache.flume.api.NettyAvroRpcClient.configure(NettyAvroRpcClient.java:634)] Using default maxIOWorkers
2015-08-25 09:10:43,548 (main) [DEBUG - org.apache.flume.client.avro.AvroCLIClient.run(AvroCLIClient.java:234)] Finished
2015-08-25 09:10:43,548 (main) [DEBUG - org.apache.flume.client.avro.AvroCLIClient.run(AvroCLIClient.java:237)] Closing reader
2015-08-25 09:10:43,550 (main) [DEBUG - org.apache.flume.client.avro.AvroCLIClient.run(AvroCLIClient.java:241)] Closing RPC client
2015-08-25 09:10:43,567 (main) [DEBUG - org.apache.flume.client.avro.AvroCLIClient.main(AvroCLIClient.java:84)] Exiting

需要注意:-H cloud004中的cloud004是agent節點地址,-F /usr/java/hadoop/app/flume/mydata/2.log 是發送的日誌文件內容。

7、查看HDFS上同步過來的數據。

[hadoop@cloud001 hadoop]$ hadoop fs -ls /data/flume/
Found 1 items
-rw-r--r--   3 hadoop supergroup         21 2015-08-25 09:11 /data/flume/FlumeData.1440465043429

至此flume一個簡單的數據收集過程已經分析完畢,大家可以根據需求完成其他實現方式,這裏就不多說。

Flume 案例分析

下面我們看一下flume的實際應用場景,其示例圖如下所示。

在上面的應用場景中,主要可以分爲以下幾個步驟。

1、首先採用flume進行日誌收集。

2、採用HDFS進行日誌的存儲。

3、採用MapReduce/Hive進行日誌分析。

4、將分析後的格式化日誌存儲到Mysql數據庫中。

5、最後前端查詢,實現數據可視化展示。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章