Flume從入門到放棄(一)

1 Flume簡介

1.1 Flume概述

Flume是Cloudera提供的一個高可用的,高可靠的,分佈式的海量日誌採集、聚合和傳輸的系統。Flume的使用不僅限於日誌數據聚合,由於數據源是可定製的,因此Flume可用於傳輸大量事件數據,包括但不限於網絡流量數據,社交媒體生成的數據,電子郵件消息以及幾乎所有可能的數據源。Flume基於流式架構,靈活簡單。

當前Flume有兩個版本Flume 0.9X版本的統稱Flume-og(Cloudera Flume),Flume1.X版本的統稱Flume-ng(Apache Flume)。由於Flume-ng經過重大重構,與Flume-og有很大不同,使用時請注意區分。

1.2 架構

Flume事件定義爲具有字節有效負載和可選字符串屬性集的數據流單位。Flume Agent是一個(JVM)進程,承載了組件,事件通過這些組件從外部源流到下一個目標(hop)。
flume
外部Source(如Web服務器)以目標Flume Source可以識別的格式將事件發送到Flume。例如,Avro Flume Source可用於從Avro Client或另一個Flume agent的Avro Sink接收Avro事件。可以使用Thrift Flume Source定義類似的流程,以接收來自Thrift Sink或Flume Thrift Rpc客戶端或以Flume Thrift協議生成的任何語言編寫的Thrift客戶端的事件,Flume Source收到事件後,會將其存儲到一個或多個Channel,該Channel是一個被動存儲,用於保留事件,直到被Flume Sink消耗爲止,Sink從通道中刪除事件,並將其放入HDFS之類的外部存儲庫(通過Flume HDFS Sink),或將其轉發到流中下一個Flume Agent的Flume Source。給定Agent中的Source和Sink與通道中上傳的事件異步運行。

1.2.1 Agent

Agent是一個JVM進程,它以事件的形式將數據從源頭送至目的,是Flume數據傳輸的基本單元。Agent主要有3個部分組成,Source、Channel、Sink。 Flume的數據流由事件(Event)貫穿始終。事件是Flume的基本數據單位,它攜帶日誌數據(字節數組形式)並且攜帶有頭信息,這些Event由Agent外部的Source生成,當Source捕獲事件後會進行特定的格式化,然後Source會把事件推入(單個或多個)Channel中。你可以把Channel看作是一個緩衝區,它將保存事件直到Sink處理完該事件。Sink負責持久化日誌或者把事件推向另一個Source。

1.2.2 Source

Source是負責接收數據到Flume Agent的組件。Source組件可以處理各種類型、各種格式的日誌數據。包括:

同一個Source可以關聯多個Channel。

1.2.3 Channel

Channel是位於Source和Sink之間的緩衝區。Channel允許Source和Sink運作在不同的速率上。Channel是線程安全的,可以同時處理幾個Source的寫入操作和幾個Sink的讀取操作。

Flume支持的Channel有:

1.2.4 Sink

Sink不斷地輪詢Channel中的事件且批量地移除它們,並將這些事件批量寫入到存儲或索引系統、或者被髮送到另一個Flume Agent。Sink是完全事務性的。在從Channel批量刪除數據之前,每個Sink用Channel啓動一個事務。批量事件一旦成功寫出到存儲系統或下一個Flume Agent,Sink就利用Channel提交事務。事務一旦被提交,該Channel從自己的內部緩衝區刪除事件。

Flume支持的Sink有:

1.2.5 Event

傳輸單元, Flume 數據傳輸的基本單元,以 Event 的形式將數據從源頭送至目的地。Event 由 Header 和 Body 兩部分組成, Header 用來存放該 event 的一些屬性,爲 K-V 結構,Body 用來存放該條數據,形式爲字節數組。

1.3 特點

  • 複雜流動(Complex flows):支持構建multi-hop流程,事件在到達最終目的地前可通過多個Agent傳遞,同時支持fan-in和fan-out流程,上下文路由和備份路由(故障轉移)。
  • 可靠性(Reliability):Flume使用事務性方法來確保事件的可靠傳遞。當節點出現故障時,日誌能夠被傳送到其他節點上而不會丟失。Flume提供了三種級別的可靠性保障,從強到弱依次分別爲:end-to-end(收到數據agent首先將event寫到磁盤上,當數據傳送成功後,再刪除;如果數據發送失敗,可以重新發送。),Store on failure(這也是scribe採用的策略,當數據接收方crash時,將數據寫到本地,待恢復後,繼續發送),Besteffort(數據發送到接收方後,不會進行確認)。
  • 可恢復性(Reliability):支持File Channel。

2 數據獲取方式

Flume支持多種機制來從外部源獲取數據。

2.1 RPC

Flume發行版中包含的Avro客戶端可以使用avro RPC機制將給定文件發送到Flume Avro Source

#將/usr/logs/log.10發送到localhost:41414的Avro Source
$ bin/flume-ng avro-client -H localhost -p 41414 -F /usr/logs/log.10

2.2 Exec

exec source執行一個給定的命令並使用輸出。單個“行”輸出(文字後跟回車符(’\ r’)或換行符(’\ n’)或兩者一起)。如:

a2.sources.r2.type = exec
a2.sources.r2.command = tail -F /tmp/root/hive.log
a2.sources.r2.shell = /bin/bash -c

source將通過linux命令去獲取數據

2.3 Network streams

Flume支持以下機制從常用的日誌流類型讀取數據,例如:

  1. Avro
  2. Thrift
  3. Syslog
  4. Netcat

3 Flume的部署類型

3.1 單一流程(one-agent flow)

one-agent

3.2 多代理流程(multi-agent flow)

multi-agent
爲了使數據跨多個代理或躍點流動,前一個代理的sink和當前躍點的source需要是avro類型並且sink指向source的主機名(或IP地址)和端口。可以將多個Agent順序連接起來,這是最簡單的情況,一般情況下,應該控制這種順序連接的Agent 的數量,因爲數據流經的路徑變長了,如果不考慮failover的話,出現故障將影響整個Flow上的Agent收集服務。

3.3 流合併(Consolidation)

Consolidation
這種情況應用的場景比較多,比如要收集Web網站的用戶行爲日誌, Web網站爲了可用性使用的負載集羣模式,每個節點都產生用戶行爲日誌,可以爲每 個節點都配置一個Agent來單獨收集日誌數據,然後多個Agent將數據最終匯聚到一個用來存儲數據存儲系統,如HDFS上。

3.4 多路複用流程(Multiplexing the flow)

Multiplexing the flow
將多種日誌混合在一起流入一個agent,可以agent中將混雜的日誌流分開,然後給每種日誌建立一個自己的傳輸通道,也可以設置成複製流,每個通道都接收所有的流。

4 快速入門

4.1 安裝部署Flume

  1. apache-flume-1.9.0-bin.tar.gz上傳到linux的/opt/software目錄下
  2. 解壓apache-flume-1.9.0-bin.tar.gz/opt/module/目錄下
    [root@iZnq8v4wpstsagZ software]# tar -zxf apache-flume-1.7.0-bin.tar.gz -C /opt/module/
    
  3. apache-flume-1.7.0-bin/conf下的flume-env.sh.template文件修改爲flume-env.sh,並配置flume-env.sh文件
    [root@iZnq8v4wpstsagZ conf]# mv flume-env.sh.template flume-env.sh
    [root@iZnq8v4wpstsagZ conf]# vi flume-env.sh
    export JAVA_HOME=/opt/module/jdk1.8.0_144
    

4.2 Flume入門案例

4.2.1 監控端口數據官方案例

需求: 使用 Flume 監聽一個端口, 收集該端口數據,並打印到控制檯。
實現步驟:

  1. 安裝netcat工具
    [root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# sudo yum install -y nc
    
  2. apache-flume-1.9.0-bin目錄下創建job/flume-netcat-logger.conf文件夾及文件
    [root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# mkdir job
    [root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# touch job/flume-netcat-logger.conf
    
  3. 編寫flume-netcat-logger.conf配置文件
    [root@iZnq8v4wpstsagZ job]# vim flume-netcat-logger.conf
    #flume-netcat-logger.conf:單節點Flume配置
    
    #命名Agent a1的組件
    a1.sources  =  r1 
    a1.sinks  =  k1 
    a1.channels  =  c1
    
    #配置source
    a1.sources.r1.type  =  netcat 
    a1.sources.r1.bind  =  127.0.0.1
    a1.sources.r1.port  =  44444
    
    #配置sink
    a1.sinks.k1.type  =  logger
    
    #緩存事件到Memory Channel
    a1.channels.c1.type = memory
    a1.channels.c1.capacity = 1000 
    a1.channels.c1.transactionCapacity = 100
    
    #將source和sink綁定到channel
    a1.sources.r1.channels = c1 
    a1.sinks.k1.channel = c1
    
  4. 運行flume
    [root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# bin/flume-ng agent --conf conf --conf-file job/flume-netcat-logger.conf --name a1 -Dflume.root.logger=INFO,console[root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# bin/flume-ng agent --c conf -f job/flume-netcat-logger.conf -n a1 -Dflume.root.logger=INFO,console
    
    參數說明:
  • –conf/-c:表示配置文件存儲在 conf/目錄
  • –name/-n:表示給 agent 起名爲 a1
  • –conf-file/-f:flume 本次啓動讀取的配置文件是在 job 文件夾下的flume-netcat-logger.conf
  • -Dflume.root.logger=INFO,console :-D 表示 flume 運行時動態修改 flume.root.logger
    參數屬性值,並將控制檯日誌打印級別設置爲 INFO 級別。日誌級別包括:log、 info、 warn、
    error
  1. 使用netcat客戶端測試
    [root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# nc -v 127.0.0.1 44444
    hello
    

4.2.2 實時監控單個追加文件

需求: 實時監控 Hive 日誌,並上傳到 HDFS 中。
實現步驟:

  1. Flume 要想將數據輸出到 HDFS,須持有 Hadoop 相關 jar 包,將以下jar包copy到/opt/module/apache-flume-1.9.0-bin/lib目錄下
    commons-configuration-1.6.jar
    hadoop-auth-2.7.2.jar
    hadoop-common-2.7.2.jar
    hadoop-hdfs-2.7.2.jar
    commons-io-2.4.jar
    htrace-core-3.1.0-incubating.jar
    
  2. apache-flume-1.9.0-bin/job目錄下創建flume-file-hdfs.conf配置文件
    [root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# vim job/flume-file-hdfs.conf
    # Name the components on this agent
    a2.sources = r2
    a2.sinks = k2
    a2.channels = c2
    # Describe/configure the source
    a2.sources.r2.type = exec
    a2.sources.r2.command = tail -F /tmp/root/hive.log
    a2.sources.r2.shell = /bin/bash -c
    # Describe the sink
    a2.sinks.k2.type = hdfs
    a2.sinks.k2.hdfs.path = hdfs://127.0.0.1:9000/flume/%Y%m%d/%H
    #上傳文件的前綴
    a2.sinks.k2.hdfs.filePrefix = logs-
    #是否按照時間滾動文件夾
    a2.sinks.k2.hdfs.round = true
    #多少時間單位創建一個新的文件夾
    a2.sinks.k2.hdfs.roundValue = 1
    #重新定義時間單位
    a2.sinks.k2.hdfs.roundUnit = hour
    #是否使用本地時間戳
    a2.sinks.k2.hdfs.useLocalTimeStamp = true
    #積攢多少個 Event 才 flush 到 HDFS 一次
    a2.sinks.k2.hdfs.batchSize = 100
    #設置文件類型,可支持壓縮
    a2.sinks.k2.hdfs.fileType = DataStream
    #多久生成一個新的文件
    a2.sinks.k2.hdfs.rollInterval = 30
    #設置每個文件的滾動大小
    a2.sinks.k2.hdfs.rollSize = 134217700
    #文件的滾動與 Event 數量無關
    a2.sinks.k2.hdfs.rollCount = 0
    # Use a channel which buffers events in memory
    a2.channels.c2.type = memory
    a2.channels.c2.capacity = 1000
    a2.channels.c2.transactionCapacity = 100
    # Bind the source and sink to the channel
    a2.sources.r2.channels = c2
    a2.sinks.k2.channel = c2
    
    對於所有與時間相關的轉義序列, Event Header 中必須存在以 “timestamp”的 key(除非
    hdfs.useLocalTimeStamp 設置爲 true,此方法會使用 TimestampInterceptor 自動添加
    timestamp)。
    a3.sinks.k3.hdfs.useLocalTimeStamp = true
  3. 運行Flume
[root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# bin/flume-ng agent --conf conf/ --name a2 --conf-file job/flume-file-hdfs.conf
  1. 運行Hive併產生日誌
[root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# hive
hive (default)> select * from dept order id;

4.2.3 實時監控目錄下多個新文件

需求: 使用 Flume 監聽整個目錄的文件,並上傳至 HDFS。
實現步驟:

  1. apache-flume-1.9.0-bin/job目錄下創建flume-dir-hdfs.conf配置文件
    [root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# vim job/flume-dir-hdfs.conf
    a3.sources = r3
    a3.sinks = k3
    a3.channels = c3
    # Describe/configure the source
    a3.sources.r3.type = spooldir
    a3.sources.r3.spoolDir = /opt/module/apache-flume-1.9.0-bin/upload
    a3.sources.r3.fileSuffix = .COMPLETED
    a3.sources.r3.fileHeader = true
    #忽略所有以.tmp 結尾的文件,不上傳
    a3.sources.r3.ignorePattern = ([^ ]*\.tmp)
    # Describe the sink
    a3.sinks.k3.type = hdfs
    a3.sinks.k3.hdfs.path =hdfs://127.0.0.1:9000/flume/upload/%Y%m%d/%H
    #上傳文件的前綴
    a3.sinks.k3.hdfs.filePrefix = upload-
    #是否按照時間滾動文件夾
    a3.sinks.k3.hdfs.round = true
    #多少時間單位創建一個新的文件夾
    a3.sinks.k3.hdfs.roundValue = 1
    #重新定義時間單位
    a3.sinks.k3.hdfs.roundUnit = hour
    #是否使用本地時間戳
    a3.sinks.k3.hdfs.useLocalTimeStamp = true
    #積攢多少個 Event 才 flush 到 HDFS 一次
    a3.sinks.k3.hdfs.batchSize = 100
    #設置文件類型,可支持壓縮
    a3.sinks.k3.hdfs.fileType = DataStream
    #多久生成一個新的文件
    a3.sinks.k3.hdfs.rollInterval = 60
    #設置每個文件的滾動大小大概是 128M,略小於block比較好
    a3.sinks.k3.hdfs.rollSize = 134217700
    #文件的滾動與 Event 數量無關
    a3.sinks.k3.hdfs.rollCount = 0
    # Use a channel which buffers events in memory
    a3.channels.c3.type = memory
    a3.channels.c3.capacity = 1000
    a3.channels.c3.transactionCapacity = 100
    # Bind the source and sink to the channel
    a3.sources.r3.channels = c3
    a3.sinks.k3.channel = c3
    
  2. 運行Flume
    [root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# bin/flume-ng agent --conf conf/ --name a3 --conf-file job/flume-dir-hdfs.conf
    
  3. 向 upload 文件夾中添加文件
[root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# mkdir upload
[root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# touch upload/test.txt
[root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# touch upload/test.tmp
[root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# touch upload/test.log

spooldir Source監控的目錄下文件名不可以重名,不然會導致Flume報錯無法正常運行。不要在監控目錄中創建並持續修改文件,Flume掃描到第一次保存的文件上傳完成後會以.COMPLETED結尾,之後修改將不會觸發事件,被監控文件夾每500ms掃描一次文件變動。

4.2.4 實時監控目錄下的多個追加文件

Exec source 適用於監控一個實時追加的文件, 但不能保證數據不丟失; Spooldir Source 能夠保證數據不丟失,且能夠實現斷點續傳, 但延遲較高,不能實時監控文件改動;而 Taildir Source 既能夠實現斷點續傳,又可以保證數據不丟失,還能夠進行實時監控文件改動。

需求: 使用 Flume 監聽整個目錄的實時追加文件,並上傳至 HDFS。
實現步驟:

  1. apache-flume-1.9.0-bin/job目錄下創建flume-taildir-hdfs.conf配置文件
[root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# vim job/flume-taildir-hdfs.conf
a4.sources = r4
a4.sinks = k4
a4.channels = c4
# Describe/configure the source
a4.sources.r4.type = TAILDIR
#記錄每個文件的傳輸位置的索引點
a4.sources.r4.positionFile = /opt/module/apache-flume-1.9.0-bin/tail_dir.json
a4.sources.r4.filegroups = f1
a4.sources.r4.filegroups.f1 = /opt/module/apache-flume-1.9.0-bin/files/file.*
# Describe the sink
a4.sinks.k4.type = hdfs
a4.sinks.k4.hdfs.path = hdfs://127.0.0.1:9000/flume/upload/%Y%m%d/%H
#上傳文件的前綴
a4.sinks.k4.hdfs.filePrefix = upload-
#是否按照時間滾動文件夾
a4.sinks.k4.hdfs.round = true
#多少時間單位創建一個新的文件夾
a4.sinks.k4.hdfs.roundValue = 1
#重新定義時間單位
a4.sinks.k4.hdfs.roundUnit = hour
#是否使用本地時間戳
a4.sinks.k4.hdfs.useLocalTimeStamp = true
#積攢多少個 Event 才 flush 到 HDFS 一次
a4.sinks.k4.hdfs.batchSize = 100
#設置文件類型,可支持壓縮
a4.sinks.k4.hdfs.fileType = DataStream
#多久生成一個新的文件
a4.sinks.k4.hdfs.rollInterval = 60
#設置每個文件的滾動大小大概是 128M
a4.sinks.k4.hdfs.rollSize = 134217700
#文件的滾動與 Event 數量無關
a4.sinks.k4.hdfs.rollCount = 0
# Use a channel which buffers events in memory
a4.channels.c4.type = memory
a4.channels.c4.capacity = 1000
a4.channels.c4.transactionCapacity = 100
# Bind the source and sink to the channel
a4.sources.r4.channels = c4
a4.sinks.k4.channel = c4

  1. 運行Flume
[root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# bin/flume-ng agent --conf conf/ --name a4 --conf-file job/flume-taildir-hdfs.conf
  1. 向 files 文件夾中追加內容
[root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# mkdir files
[root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# echo hello >> file1.txt
[root@iZnq8v4wpstsagZ apache-flume-1.9.0-bin]# echo world >> file2.txt

Taildir Source 維護了一個 json 格式的 position File,其會定期的往 position File中更新每個文件讀取到的最新的位置,因此能夠實現斷點續傳。Position File 的格式如下:

{"inode":2496272,"pos":12,"file":"/opt/module/apache-flume-1.9.0-bin/files/file1.txt"}
{"inode":2496275,"pos":12,"file":"/opt/module/apache-flume-1.9.0-bin/files/file2.txt"}

Linux 中儲存文件元數據的區域就叫做 inode, 每個 inode 都有一個號碼,操作系統用 inode 號碼來識別不同的文件, Unix/Linux 系統內部不使用文件名,而使用 inode號碼來識別文件

4.3 在配置文件中使用環境變量

Flume可以替換配置中值的環境變量,如:

a1.sources = r1
a1.sources.r1.type = netcat
a1.sources.r1.bind = 0.0.0.0
a1.sources.r1.port = ${NC_PORT}
a1.sources.r1.channels = c1

可以通過代理調用上的Java系統屬性來啓用,如:

NC_PORT=44444 bin/flume-ng agent -c conf/ -f job/netcat-flume-logger.conf -n a1 -Dflume.root.logger=INFO,console -DpropertiesImplementation=org.apache.flume.node.EnvVarResolverProperties

也可以用其他方式配置環境變量,包括在conf/flume-env.sh中設置

4.4 第三方插件

Flume具有完全基於插件的體系結構。Flume擁有很多開箱即用的sources、channels、sinks、serializers,並且提供許多與Flume解耦的實現方案。雖然Flume可以通過在flume-env.sh文件添加用戶自定義的Flume組件jars到FLUME_CLASSPATH中,但Flume支持在$FLUME_HOME/plugins.d目錄下自動獲取特定格式打包的插件,這使插件的管理更加容易。

每個插件目錄在plugins.d目錄下最多可以有三個子目錄:

  1. lib:插件的jar(s)
  2. libext:該插件的依賴jar(s)
  3. native:任何所需的本地庫,如的.so文件
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章