Flume介紹
1、概述
- Flume最早是Cloudera提供的日誌收集系統,後貢獻給Apache
- Flume是一個高可用的,高可靠的 、健壯性,分佈式的海量日誌採集、聚合和傳輸的系統
- Flume支持在日誌系統中定製各類數據發送方,用於收集數據(source)
- Flume提供對數據進行簡單處理,並寫到各種數據接受方(可定製)的能力(sink)。
2、版本
- Flume0.9X:又稱Flume-og,老版本的flume,需要引入zookeeper集羣管理,性能也較低(單線程工作)
- Flume1.X:又稱Flume-ng。新版本需要引入zookeeper,和flume-og不兼容
3、Flume的特性
- 可靠性:事務型的數據傳遞,保證數據的可靠性。一個日誌交給flume來處理,不會出現此日誌丟失或未被處理的情況
- 可恢復性:通道可以以內存或文件的方式實現,內存更快,但不可恢復。文件較慢但提供了可恢復性
4、event事件
一、Flume總體架構圖
二、event 事件
- event的相關概念:Flume的核心是把數據從數據源(source)收集過來,在將收集到的數據送到指定的目的地(sink)。爲了保證輸送的過程一定成功,在送到目的地(sink)之前,會先緩存數據(channel),待數據真正到達目的地(sink)後,flume在刪除自己緩存的數據。
- 在整個數據的傳輸的過程中,流動的是event,即事務保證是在event級別進行的。event將傳輸的數據進行封裝,是flume傳輸數據的基本單位,如果是文本文件,通常是一行記錄,event也是事務的基本單位。event從source,流向channel,再到sink,本身爲一個字節數組,並可攜帶headers(頭信息)信息。event代表着一個數據的最小完整單元,從外部數據源來,向外部的目的地去。簡而言之,在Flume中,每一條日誌就會封裝成一個event對象
- 一個完整的event包括:event headers、event body、event信息(即文本文件中的單行記錄),如下所以:
其中event信息就是flume收集到的日記記錄。
三、Flume的運行機制
- flume運行的核心就是agent,agent本身是一個Java進程
- agent裏面包含3個核心的組件:source—>channel—>sink,類似生產者、倉庫、消費者的架構
- source:source組件是專門用來收集數據的,可以處理各種類型、各種格式的日誌數據,包括avro、thrift、exec、jms、spooling directory、netcat、sequence generator、syslog、http、legacy、自定義等
- channel:source組件把數據收集來以後,臨時存放在channel中,即channel組件在agent中是專門用來存放臨時數據的——對採集到的數據進行簡單的緩存,可以存放在memory、jdbc、file等等
- sink:sink組件是用於把數據發送到目的地的組件,目的地包括hdfs、logger、avro、thrift、ipc、file、null、hbase、solr、自定義。
- 一個完整的工作流程:source不斷的接收數據,將數據封裝成一個一個的event,然後將event發送給channel,chanel作爲一個緩衝區會臨時存放這些event數據,隨後sink會將channel中的event數據發送到指定的地方—-例如HDFS等
- 注:只有在sink將channel中的數據成功發送出去之後,channel纔會將臨時event數據進行刪除,這種機制保證了數據傳輸的可靠性與安全性。
四、Flume的複雜流動
多個agent的數據流(多級流動)
數據流合併(扇入流)
在做日誌收集的時候一個常見的場景就是,大量的生產日誌的客戶端發送數據到少量的附屬於存儲子系統的消費者agent。例如,從數百個web服務器中收集日誌,它們發送數據到十幾個負責將數據寫入HDFS集羣的agent。
這個可在Flume中可以實現,需要配置大量第一層的agent,每一個agent都有一個avro sink,讓它們都指向同一個agent的avro source(強調一下,在這樣一個場景下你也可以使用thrift source/sink/client)。在第二層agent上的source將收到的event合併到一個channel中,event被一個sink消費到它的最終的目的地。
數據流複用(扇出流)
Flume支持多路輸出event流到一個或多個目的地。這是靠定義一個多路數據流實現的,它可以實現複製和選擇性路由一個event到一個或者多個channel。
上面的例子展示了agent foo中source扇出數據流到三個不同的channel,這個扇出可以是複製或者多路輸出。在複製數據流的情況下,每一個event被髮送所有的三個channel;在多路輸出的情況下,一個event被髮送到一部分可用的channel中,它們是根據event的屬性和預先配置的值選擇channel的。 這些映射關係應該被填寫在agent的配置文件中。
一、安裝步驟
此處還是用之前搭建的虛擬機進行安裝
1. 安裝JDK1.6以上,建議JDK1.7或者JDK1.8
2. 下載/上傳flume的安裝包
3. 解壓安裝
tar -xvf apache-flume-1.6.0-bin.tar.gz
4. 在conf目錄下,創建一個配置文件,比如:template.conf(名字可以不固定,後綴也可以不固定),添加如下配置:
複製粘貼即可,先測試一下,一會詳解配置屬性含義
#配置Agent a1 的組件
a1.sources=r1
a1.channels=c1
a1.sinks=s1
#描述/配置a1的r1
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=44444
#描述a1的s1
a1.sinks.s1.type=logger
#描述a1的c1
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
5. 進入flume的bin目錄執行: ./flume-ng agent -n a1 -c …/conf -f …/conf/template.conf -Dflume.root.logger=INFO,console
6. 新打開一個窗口通過nc來訪問:
輸入nc如果是這樣的話
這是沒有安裝nc,需要安裝一下
yum install -y nc
下面開始測試一下flume
nc localhost 44444
hello
nihao
123456789
通過nc請求flume已經返回OK
看一下之前啓動flume的窗口,已經收到了
或者通過外部http請求訪問對應的ip和端口,比如:http://192.168.199.11:44444/123123
在虛擬機這邊,會出現如下提示:
二、啓動命令
參數 描述
agent 運行一個Flume Agent
–conf,-c 指定配置文件放在什麼目錄
–conf-file,-f 指定配置文件,這個配置文件必須在全局選項的–conf參數定義的目錄下
–name,-n Agent的名稱,注意:要和配置文件裏的名字一致。
-Dproperty=value 設置一個JAVA系統屬性值。常見的:-Dflume.root.logger=INFO,console
參數 | 描述 |
---|---|
agent | 運行一個Flume Agent |
–conf,-c | 指定配置文件放在什麼目錄 |
–conf-file,-f | 指定配置文件,這個配置文件必須在全局選項的–conf參數定義的目錄下 |
–name,-n | Agent的名稱,注意:要和配置文件裏的名字一致。 |
-Dproperty=value | 設置一個JAVA系統屬性值。常見的:-Dflume.root.logger=INFO,console |
示例:./flume-ng agent -n a1 -c …/conf -f …/conf/template.conf -Dflume.root.logger=INFO,console
通過以上的介紹我們知道有三個重要組件分別爲source、channel、sink以下先詳解每一個組件,在結合組件做實例
一、source 詳解總共6個
1、Avro Source詳解(使用率極高)
一、概述
- 監聽Avro 端口來接收外部avro客戶端的事件流
- avro-source接收到的是經過avro序列化後的數據,然後反序列化數據繼續傳輸。
- 源數據必須是經過avro序列化後的數據
- 利用Avro source可以實現多級流動、扇出流、扇入流等效果
- 可以接收通過flume提供的avro客戶端發送的日誌信息
二、可配選項說明
配置項 | 說明 |
---|---|
channels | 綁定通道 |
type | avro |
bind | 需要監聽的主機名或IP |
port | 要監聽的端口 |
threads | 工作線程最大線程數 |
selector.* | 選擇器配置 |
interceptors.* | 攔截器配置 |
三、簡單示例
- 在conf文件夾下新建配置文件:avrosource.conf
- 添加如下內容:
#配置Agent a1 的組件
a1.sources=r1
a1.channels=c1
a1.sinks=s1
#描述/配置a1的source1
a1.sources.r1.type=avro
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=44444
#描述sink
a1.sinks.s1.type=logger
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
- 執行啓動指令,如果出現如下提示,證明啓動成功
./flume-ng agent -n a1 -c ../conf -f ../conf/avrosource.conf -Dflume.root.logger=INFO,console
4. 在flume根目錄創建mydata文件夾,在mydata內創建1.txt,寫一個Hello然後保存退出
6. 在bin目錄執行agent-avro客戶端指令:./flume-ng avro-client -H 0.0.0.0 -p 44444 -F …/mydata/1.txt -c …/conf/
可以看到文件內的hello反序列化到Flume中
2、Exec Source詳解(使用率中)
一、概述
- 可以將命令產生的輸出作爲源來進行傳遞,例如捕獲ping命令
二、可配置選項說明
配置項 | 說明 |
---|---|
channels | 綁定的通道 |
type | exec |
command | 要執行的命令 |
selector.* | 選擇器配置 |
interceptors.* | 攔截器列表配置 |
三、示例:
- 在conf文件夾下新建配置文件:execsource.conf
- 添加如下內容:
#配置Agent a1 的組件
a1.sources=r1
a1.channels=c1
a1.sinks=s1
#描述/配置a1的source1
a1.sources.r1.type=exec
a1.sources.r1.command=ping www.baidu.com
#描述sink
a1.sinks.s1.type=logger
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
-
進入到bin目錄執行指令:./flume-ng agent --conf …/conf --conf-file …/conf/execsource.conf --name a1 -Dflume.root.logger=INFO,console
-
結果爲ping 百度返回的結果
3、Spooling Directory Source詳解(使用率高)
一、概述
- flume會持續監聽指定的目錄,把放入這個目錄中的文件當做source來處理
- 注意:一旦文件被放到“自動收集”目錄中後,便不能修改,如果修改,flume會報錯
- 此外,也不能有重名的文件,如果有,flume也會報錯。
二、可配置選項說明
配置項 | 說明 |
---|---|
channels | 綁定通道 |
type | spooldir |
spoolDir | 讀取文件的路徑,即"蒐集目錄" |
selector.* | 選擇器配置 |
interceptors.* | 攔截器配置 |
三、示例
- 在conf文件夾下新建配置文件:spodire.conf
- 添加如下內容:
#配置Agent a1 的組件
a1.sources=r1
a1.channels=c1
a1.sinks=s1
#描述/配置a1的source1
a1.sources.r1.type=spooldir
a1.sources.r1.spoolDir=/home/data
#描述sink
a1.sinks.s1.type=logger
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
- 在home下創建data文件夾
- 根據指定的配置文件,啓動flume
./flume-ng agent --conf ../conf --conf-file ../conf/spodire.conf --name a1 -Dflume.root.logger=INFO,console
- 向指定的文件目錄下傳送一個日誌文件,發現flume的控制檯打印相關的信息。此外,會發現被處理的文件,會追加一個後綴:completed,表示已處理完。
我們剛剛有創建一個1.txt。所以直接複製過去即可
cp /home/software/apache-flume-1.6.0-bin/mydata/1.txt data/
4、NetCat Source詳解(使用率高)
一、概述
1. 一個NetCat Source用來監聽一個指定端口,並接收監聽到的數據
2. 接收的數據是字符串形式
二、可配置選項說明
配置項 | 說明 |
---|---|
channels | 綁定通道 |
type | netcat |
port | 指定要綁定到的端口號 |
selector.* | 選擇器配置 |
interceptors.* | 攔截器配置 |
三、示例
- 在conf文件夾下新建配置文件:netcat.conf
- 添加如下內容:
#配置Agent a1 的組件
a1.sources=r1
a1.channels=c1
a1.sinks=s1
#描述/配置a1的r1
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=44444
#描述a1的s1
a1.sinks.s1.type=logger
#描述a1的c1
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
- 進入flume的bin目錄執行:
./flume-ng agent --conf ../conf --conf-file ../conf/netcat.conf --name a1 -Dflume.root.logger=INFO,console
- 通過nc來訪問
nc localhost 44444
hello
5、Squence Generator Source詳解(使用率低)
一、概述
- 一個簡單的序列發生器,不斷的產生事件,值是從0開始每次遞增1
- 主要用來測試
二、可配置選項說明
配置項 | 說明 |
---|---|
channels | 綁定的通道 |
type | seq |
selector.* | 選擇器配置 |
interceptors.* | 攔截器配置 |
batchSize | 遞增步長, 默認是1 |
三、示例
- 在conf文件夾下新建配置文件:squence.conf
- 添加如下內容:
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=seq
#描述sink
a1.sinks.s1.type=logger
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
3.啓動flume
./flume-ng agent --conf ../conf --conf-file ../conf/squence.conf --name a1 -Dflume.root.logger=INFO,console
可以直接看到
6、HTTP Source詳解(使用率高)
一、概述
- 此Source接受HTTP的GET和POST請求作爲Flume的事件
- GET方式只用於試驗,所以實際使用過程中以POST請求居多
- 如果想讓flume正確解析Http協議信息,比如解析出請求頭、請求體等信息,需要提供一個可插拔的"處理器"來將請求轉換爲事件對象,這個處理器必須實現HTTPSourceHandler接口。
- 這個處理器接受一個 HttpServletRequest對象,並返回一個Flume Envent對象集合。
二、常用Handler
JSONHandler
1. 可以處理JSON格式的數據,並支持UTF-8 UTF-16 UTF-32字符集
2. 該handler接受Event數組,並根據請求頭中指定的編碼將其轉換爲Flume Event
3. 如果沒有指定編碼,默認編碼爲UTF-8
4. 格式:
[
{
“headers” : {
“timestamp” : “434324343”,
“host” : “random_host.example.com”
}
“body” : “random_body”
},
{
“headers” : {
“namenode” : “namenode.example.com”,
“datanode” : “random_datanode.example.com”
},
“body” : “really_random_body”
}
]
BlobHandler
1. BlobHandler是一種將請求中上傳文件信息轉化爲event的處理器
2. BlobHandler適合大文件的傳輸
三、可配置選項說明
配置項 | 說明 |
---|---|
channels | 綁定的通道 |
type | http |
selector.* | 選擇器配置 |
interceptors.* | 攔截器配置 |
port | 端口 |
四、示例:
- 在conf文件夾下新建配置文件:httpsource.conf
- 添加如下內容:
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=http
a1.sources.r1.port=8888
#描述sink
a1.sinks.s1.type=logger
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
- 執行啓動命令
./flume-ng agent --conf ../conf --conf-file ../conf/httpsource.conf --name a1 -Dflume.root.logger=INFO,console
- 執行curl 命令,模擬一次http的Post請求:curl -X POST -d ‘[{“headers”:{“a”:“a1”,“b”:“b1”},“body”:“hello flume”}]’ http://0.0.0.0:8888
一、channel詳解
1、Memory Channel(使用率極高)
一、概述
1. 事件將被存儲在內存中(指定大小的隊列裏)
2. 非常適合那些需要高吞吐量且允許數據丟失的場景下
二、可配置選項說明
配置項 | 說明 |
---|---|
type | memory |
capacity | 100 事件存儲在信道中的最大數量建議實際工作調節:10萬首先估算出每個event的大小,然後再服務的內存來調節 |
transactionCapacity | 100 每個事務中的最大事件數建議實際工作調節:1000~3000 |
三、上面的示例一直使用的都是memory所以此處不再演示
2、File Channel(使用率低)
一、概述
- 將數據臨時存儲到計算機的磁盤的文件中
- 性能比較低,但是即使程序出錯數據不會丟失
二、可配置選項說明
配置項 | 說明 |
---|---|
type | file |
dataDirs | 指定存放的目錄,逗號分隔的目錄列表,用以存放日誌文件。使用單獨的磁盤上的多個目錄可以提高文件通道效率。 |
三、示例
- 在conf文件夾下新建配置文件:filechannel.conf
- 添加如下內容:
a1.sources=r1
a1.channels=c1
a1.sinks=s1
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=8888
a1.sinks.s1.type=logger
a1.channels.c1.type=file
a1.channels.c1.dataDirs=/home/filechannel
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
3可以在/home/filechannel下看到文件
使用nc發送數據,可以看到文件大小的變化
3、JDBC Channel
- 事件會被持久化(存儲)到可靠的數據庫裏
- 目前只支持嵌入式Derby數據庫。但是Derby數據庫不太好用,所以JDBC Channel目前僅用於測試,不能用於生產環境。
4、內存溢出 Channel
- 優先把Event存到內存中,如果存不下,在溢出到文件中
- 目前處於測試階段,還未能用於生產環境
一、sink詳解
1、Logger Sink
一、概述
- 記錄指定級別(比如INFO,DEBUG,ERROR等)的日誌,通常用於調試
- 要求,在 --conf(-c )參數指定的目錄下有log4j的配置文件
- 根據設計,logger sink將body內容限制爲16字節,從而避免屏幕充斥着過多的內容。如果想要查看調試的完整內容,那麼你應該使用其他的sink,也許可以使用file_roll sink,它會將日誌寫到本地文件系統中。
二、可配置項說明
配置項 | 說明 |
---|---|
channel | 綁定通道 |
type | logger |
三、示例
這裏就不過多敘述了。上門的示例都是使用的logger
#配置Agent a1 的組件
a1.sources=r1
a1.channels=c1
a1.sinks=s1
#描述/配置a1的r1
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=44444
#描述a1的s1
a1.sinks.s1.type=logger
#描述a1的c1
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
2、File_roll Sink
一、概述
1. 在本地系統中存儲事件
2. 每隔指定時長生成文件保存這段時間內收集到的日誌信息
二、可配置選項說明
配置項 | 說明 |
---|---|
channel | 綁定通道 |
type | file_roll |
sink.directory | 文件被存儲的目錄 |
sink.rollInterval | 30 記錄日誌到文件裏,每隔30秒生成一個新日誌文件。如果設置爲0,則禁止滾動,從而導致所有數據被寫入到一個文件中。 |
三、示例
- 在conf文件夾下新建配置文件:file.conf
- 添加如下內容:
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=8888
#描述sink
a1.sinks.s1.type=file_roll
a1.sinks.s1.sink.directory=/home/rolldata
a1.sinks.s1.sink.rollInterval=60
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
- 創建指定的文件目錄 /home/rolldata
- 啓動測試
./flume-ng agent --conf ../conf --conf-file ../conf/file.conf --name a1 -Dflume.root.logger=INFO,console
然後用nc命令發送數據到Flume,在/home/rolldata 下可以看到生成的文件。編輯文件可以看到具體的內容
3、HDFS Sink
一、概述
- 此Sink將事件寫入到Hadoop分佈式文件系統HDFS中
- 目前它支持創建文本文件和序列化文件,並且對這兩種格式都支持壓縮
- 這些文件可以分卷,按照指定的時間或數據量或事件的數量爲基礎
- 它還通過類似時間戳或機器屬性對數據進行 buckets/partitions 操作
- HDFS的目錄路徑可以包含將要由HDFS替換格式的轉移序列用以生成存儲事件的目錄/文件名
- 使用這個Sink要求haddop必須已經安裝好,以便Flume可以通過hadoop提供的jar包與HDFS進行通信
二、可配置選項說明
配置項 | 說明 |
---|---|
channel | 綁定的通道 |
type | hdfs |
hdfs.path | HDFS 目錄路徑 (hdfs://namenode/flume/webdata/) |
hdfs.inUseSuffix .tmp | Flume正在處理的文件所加的後綴 |
hdfs.rollInterval | 文件生成的間隔事件,默認是30,單位是秒 |
hdfs.rollSize | 生成的文件大小,默認是1024個字節 ,0表示不開啓此項 |
hdfs.rollCount | 每寫幾條數據就生成一個新文件,默認數量爲10每寫幾條數據就生成一個新文件, |
hdfs.fileType | SequenceFile/DataStream/CompressedStream 文件格式,默認值:SequenceFile。當使用DataStream時候,文件不會被壓縮,不需要設置hdfs.codeC;當使用CompressedStream時候,必須設置一個正確的hdfs.codeC值; |
hdfs.retryInterval | 80 Time in seconds between consecutive attempts to close a file. Each close call costs multiple RPCround-trips to the Namenode, so setting this too low can cause a lot of load on the name node. If set to 0 or less, the sink will not attempt to close the file if the first attempt fails, and may leave the file open or with a ”.tmp” extension. 關閉文件的時間間隔 |
.
三、示例
- 在conf文件夾下新建配置文件:hdfs.conf
- 添加如下內容:
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=8888
#描述sink
a1.sinks.s1.type=hdfs
a1.sinks.s1.hdfs.path=hdfs://test1:9000/flume
a1.sinks.s1.hdfs.fileType=DataStream
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
3.啓動測試
./flume-ng agent --conf ../conf --conf-file ../conf/hdfs.conf --name a1 -Dflume.root.logger=INFO,console
注意。這裏因爲我之前的文章介紹過安裝hadoop。所以此處不在表述。我hadoop配置的是hdfs://test1:9000 如果你和我不一樣請按照你的填寫
使用nc進行測試,可以看到。自動創建了flume路徑,並把內容存儲到了hdfs上
四、存在問題
- 報錯是因爲flume缺少相關hadoop的依賴jar包,找到以下的jar包,放到flume的lib目錄下即可。
commons-configuration-1.6.jar
hadoop-auth-2.5.2.jar
hadoop-common-2.5.2.jar
hadoop-hdfs-2.5.2.jar
hadoop-mapreduce-client-core-2.5.2.jar
但是一個一個找特別麻煩,所以解決辦法是將hadoop的jar包都拷貝到flume的lib目錄下:執行:scp common/* common/lib/* hdfs/* hdfs/lib/* mapreduce/* mapreduce/lib/* tools/lib/* 192.168.199.11:/home/software/apache-flume-1.6.0-bin/lib/
如果還是不行,請查看具體的錯誤進行解決
4、Avro Sink
一、概述
- 將源數據進行利用avro進行序列化之後寫到指定的節點上
- 是實現多級流動、扇出流(1到多) 扇入流(多到1) 的基礎。
二、可配置選項說明
配置項 | 說明 |
---|---|
channel | 綁定的通道 |
type | avro |
hostname | 要發送的主機 |
port | 要發往的端口號 |
三、多級流動
概述
- 讓01機的flume通過netcat source源接收數據,然後通過avro sink 發給02機
- 02機的flume利用avro source源收數據,然後通過avro sink 傳給03機
- 03機通過avro source源收數據,通過logger sink 輸出到控制檯上
實現步驟 - 準備三個節點,並安裝好flume(關閉每臺機器的防火牆)
- 複製flume到另外兩臺機器上,在另外兩臺機器上執行下面的命令
scp遠程複製,-r遞歸複製整個目錄,使用root用戶從192.168.199.11上覆制/home/software/apache-flume-1.6.0-bin到本地的/home/software/
scp -r [email protected]:/home/software/apache-flume-1.6.0-bin /home/software/
- 配置每臺flume的配置文件,我這裏統一使用avros.conf
01機的配置示例:
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=8888
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.199.12
a1.sinks.s1.port=9999
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
02機的配置示例:
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source
a1.sources.r1.type=avro
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=9999
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.199.13
a1.sinks.s1.port=9999
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
03機的配置示例:
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=avro
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=9999
#描述sink
a1.sinks.s1.type=logger
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
- 啓動測試
啓動順序爲03》02》01,啓動後可以分別在03和02上看到有連接進來
./flume-ng agent --conf ../conf --conf-file ../conf/avros.conf --name a1 -Dflume.root.logger=INFO,console
因爲01是源頭。所以沒有連接進來。我們開始在01上使用nc發送數據進行測試
在03上已經收到數據,完成多級流動了
四、扇出流
從01分別發送到02、03上面
創建配置文件:outdata.conf
01機的配置文件
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1 s2
a1.channels=c1 c2
#描述/配置a1的source1
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=8888
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.199.12
a1.sinks.s1.port=9999
a1.sinks.s2.type=avro
a1.sinks.s2.hostname=192.168.199.13
a1.sinks.s2.port=9999
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
a1.channels.c2.type=memory
a1.channels.c2.capacity=1000
a1.channels.c2.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1 c2
a1.sinks.s1.channel=c1
a1.sinks.s2.channel=c2
02,03配置示例:
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=avro
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=9999
#描述sink
a1.sinks.s1.type=logger
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
啓動測試,先啓動02、03、在啓動01.可以看到02、03有連接進來
./flume-ng agent --conf ../conf --conf-file ../conf/outdata.conf --name a1 -Dflume.root.logger=INFO,console
使用nc測試,可以看到數據被髮送到了02和03.
五、扇入流
從02、03發送到01上面
創建配置文件:indata.conf
02,03的配置示例:
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=netcat
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=8888
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.199.11
a1.sinks.s1.port=9999
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
01機的配置示例:
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=avro
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=9999
#描述sink
a1.sinks.s1.type=logger
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
先啓動01.在啓動02、03可以在01看到
有兩個連接進來。現在分別在02和03發送數據可以到01了
扇入流完成
複製模式
一、概述
- Selector 默認是複製模式(replicating),即把source複製,然後分發給多個sink
二、 可配置選項說明
配置項 | 說明 |
---|---|
selector.type | replicating 表示複製模式,source的selector如果不配置,默認就是這種模式在複製模式下,當source接收到數據後,會複製多分,分發給每一個avro sink |
selector.optional | 標誌通道爲可選,可選寫入失敗會被忽略。 |
三、示例
a1.sources = r1
a1.channels = c1 c2 c3
a1.source.r1.selector.type = replicating(這個是默認的)
a1.source.r1.channels = c1 c2 c3
#c3是可選的,向c3寫入失敗會被忽略。但是向c1,c2寫入失敗會出錯
a1.source.r1.selector.optional = c3
和扇出是一樣的。所以此處不再寫具體示例
多路複用模式
一、概述
- 在這種模式下,用戶可以指定轉發的規則。selector根據規則進行數據的分發
二、可配置選項說明
配置項 | 說明 |
---|---|
selector.type | multiplexing 表示路由模式 |
selector.header | 指定要監測的頭的名稱 |
selector.mapping.* | 匹配規則 |
selector.default | 如果未滿足匹配規則,則默認發往指定的通道 |
三、示例
01機利用http source接收數據,根據路由規則,發往02,03機。02,03通過avro source接收數據,通過logger sink 打印數據
創建配置文件:selector.conf
01機配置示例
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1 s2
a1.channels=c1 c2
#描述/配置a1的source1
a1.sources.r1.type=http
a1.sources.r1.port=8888
a1.sources.r1.selector.type=multiplexing
a1.sources.r1.selector.header=state
a1.sources.r1.selector.mapping.cn=c1
a1.sources.r1.selector.mapping.us=c2
a1.sources.r1.selector.default=c2
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.199.12
a1.sinks.s1.port=9999
a1.sinks.s2.type=avro
a1.sinks.s2.hostname=192.168.199.13
a1.sinks.s2.port=9999
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
a1.channels.c2.type=memory
a1.channels.c2.capacity=1000
a1.channels.c2.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1 c2
a1.sinks.s1.channel=c1
a1.sinks.s2.channel=c2
2. 02,03配置示例:
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=avro
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=9999
#描述sink
a1.sinks.s1.type=logger
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
接下來開始測試
分別在01機器上輸入
curl -X POST -d '[{"headers":{"state":"us","b":"b1"},"body":"hello us"}]' http://localhost:8888
curl -X POST -d '[{"headers":{"state":"cn","b":"b1"},"body":"hello cn"}]' http://localhost:8888
curl -X POST -d '[{"headers":{"state":"11111111","b":"b1"},"body":"hello 11111111"}]' http://localhost:8888
02收到
03收到,因爲03配置了default=c2,所以默認數據是往這裏發送的
Interceptor 攔截器
Timestamp Interceptor
一、概述
- 這個攔截器在事件頭中插入以毫秒爲單位的當前處理時間
- 頭的名字爲timestamp,值爲當前處理的時間戳
- 如果在之前已經有這個時間戳,則保留原有的時間戳
二、可配置項說明
配置項 | 說明 |
---|---|
type | timestamp |
preserveExisting | false 如果時間戳已經存在是否保留 |
三、配置示例
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1 s2
a1.channels=c1 c2
#描述/配置a1的source1
a1.sources.r1.type=http
a1.sources.r1.port=8888
a1.sources.r1.interceptors=i1
a1.sources.r1.interceptors.i1.type=timestamp
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.199.12
a1.sinks.s1.port=9999
a1.sinks.s2.type=avro
a1.sinks.s2.hostname=192.168.199.13
a1.sinks.s2.port=9999
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
a1.channels.c2.type=memory
a1.channels.c2.capacity=1000
a1.channels.c2.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1 c2
a1.sinks.s1.channel=c1
a1.sinks.s2.channel=c2
在01機創建timestamp.conf文件
02和03保持之前多路複用模式啓動狀態不變,可以看到02和03接收到的數據都被加上時間戳
curl -X POST -d '[{"headers":{"state":"11111111","b":"b1"},"body":"hello 11111111"}]' http://localhost:8888
Host Interceptor
一、概述
- 這個攔截器插入當前處理Agent的主機名或ip
- 頭的名字爲host或配置的名稱
- 值是主機名或ip地址,基於配置
二、可配置項說明
配置參數 | 說明 |
---|---|
type | host |
preserveExisting | false 如果主機名已經存在是否保留 |
useIP | true 如果配置爲true則用IP,配置爲false則用主機名 |
hostHeader | host 加入頭時使用的名稱 |
三、配置示例
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1 s2
a1.channels=c1 c2
#描述/配置a1的source1
a1.sources.r1.type=http
a1.sources.r1.port=8888
a1.sources.r1.interceptors=i1
a1.sources.r1.interceptors.i1.type=host
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.199.12
a1.sinks.s1.port=9999
a1.sinks.s2.type=avro
a1.sinks.s2.hostname=192.168.199.13
a1.sinks.s2.port=9999
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
a1.channels.c2.type=memory
a1.channels.c2.capacity=1000
a1.channels.c2.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1 c2
a1.sinks.s1.channel=c1
a1.sinks.s2.channel=c2
結果添加了請求地址:
Static Interceptor
一、概述
- 此攔截器允許用戶增加靜態頭信息使用靜態的值到所有事件
- 目前的實現中不允許一次指定多個頭
- 如果需要增加多個靜態頭可以指定多個Static interceptors
二、可配置項說明
配置項 | 說明 |
---|---|
type | static |
preserveExisting | true |
key | key 要增加的頭名 |
value | value 要增加的頭值 |
三、配置示例
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1 s2
a1.channels=c1 c2
#描述/配置a1的source1
a1.sources.r1.type=http
a1.sources.r1.port=8888
a1.sources.r1.interceptors=i1
a1.sources.r1.interceptors.i1.type=static
a1.sources.r1.interceptors.i1.key=addr
a1.sources.r1.interceptors.i1.value=beijing
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.199.12
a1.sinks.s1.port=9999
a1.sinks.s2.type=avro
a1.sinks.s2.hostname=192.168.199.13
a1.sinks.s2.port=9999
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
a1.channels.c2.type=memory
a1.channels.c2.capacity=1000
a1.channels.c2.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1 c2
a1.sinks.s1.channel=c1
a1.sinks.s2.channel=c2
結果可以看到addr=beijing:
UUID Interceptor
一、概述
- 這個攔截器在所有事件頭中增加一個全局一致性標誌,其實就是UUID
二、可配置項說明
配置項 | 說明 |
---|---|
type | org.apache.flume.sink.solr.morphline.UUIDInterceptor$Builder |
headerName | id 頭名稱 |
preserveExisting | true 如果頭已經存在,是否保留 |
prefix | “” 在UUID前拼接的字符串前綴 |
三、配置示例
結果示意:
Search And Replace Interceptor
一、概述
- 這個攔截器提供了簡單的基於字符串的正則搜索和替換功能。
二、可配置項說明
配置項 | 說明 |
---|---|
type | search_replace |
searchPattern | 要搜索和替換的正則表達式 |
replaceString | 要替換爲的字符串 |
charset | UTF-8 字符集編碼,默認utf-8 |
三、配置示例
發送的數據示意(比如在body裏寫一些數字):
結果示意:
Regex Filtering Interceptor
一、概述
- 此攔截器通過解析事件體去匹配給定正則表達式來篩選事件
- 所提供的正則表達式即可以用來包含或刨除事件
二、可配置項說明
配置項 | 說明 |
---|---|
type | regex_filter |
regex | ”.*” 所要匹配的正則表達式 |
excludeEvents | false 如果是true則刨除匹配的事件,false則包含匹配的事件。 |
三、配置示例
結果將過濾到以jp開頭的信息,即如果發送的是以jp開頭的信息,則收不到
Regex Filtering Interceptor
一、概述
- 使用指定正則表達式匹配事件,並將匹配到的組作爲頭加入到事件中
- 它也支持插件化的序列化器用來格式化匹配到的組在加入他們作爲頭之前
二、可配置項說明
配置項 說明
type regex_extractor
regex 要匹配的正則表達式
serializers 匹配對象列表
三、配置示例
01 define agent name, source/sink/channel
a1.sources = r1
a1.sinks = k1
a1.channels = c1
02 source,http,jsonhandler
a1.sources.r1.type = http
a1.sources.r1.bind = master
a1.sources.r1.port = 6666
a1.sources.r1.handler = org.apache.flume.source.http.JSONHandler
03 regex extractor interceptor,match event body to extract character and digital
a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type = regex_extractor
a1.sources.r1.interceptors.i1.regex = (^[a-zA-Z]*)\\s([0-9]*$) # regex匹配並進行分組,匹配結果將有兩個部分, 注意\s空白字符要進行轉義
specify key for 2 matched part
a1.sources.r1.interceptors.i1.serializers = s1 s2
key name
a1.sources.r1.interceptors.i1.serializers.s1.name = word
a1.sources.r1.interceptors.i1.serializers.s2.name = digital
04 logger sink
a1.sinks.k1.type = logger
05 channel,memory
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100
06 bind source,sink to channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
發送事件:
結果示意:
Sink Group Processor
- Sink Group允許用戶將多個Sink組合成一個實體
- Flume Sink Processor 可以通過切換組內Sink用來實現負載均衡的效果,或在一個Sink故障時切換到另一個Sink
Default Sink Processor
一、概述
- 只接受一個 Sink
- 這是默認的策略。即如果不配置Processor,用的是這個策略
二、可配置選項說明
配置項 | 說明 |
---|---|
sinks | 用空格分隔的Sink集合 |
processor.type | default |
Failover Sink Processor
一、概述
- 維護一個sink們的優先表。確保只要一個是可用的就事件就可以被處理
- 失敗處理原理是,爲失效的sink指定一個冷卻時間,在冷卻時間到達後再重新使用
- sink們可以被配置一個優先級,數字越大優先級越高
- 如果sink發送事件失敗,則下一個最高優先級的sink將會嘗試接着發送事件
- 如果沒有指定優先級,則優先級順序取決於sink們的配置順序,先配置的默認優先級高於後配置的
- 在配置的過程中,設置一個group processor ,並且爲每個sink都指定一個優先級
- 優先級必須是唯一的
- 另外可以設置maxpenalty屬性指定限定失敗時間。
二、可配置項說明
配置項 | 說明 |
---|---|
sinks | 綁定的sink |
processor.type | failover |
processor.priority | 設置優先級,注意,每個sink的優先級必須是唯一的 |
processor.maxpenalty | 30000 The maximum backoff period for the failed Sink (in millis) |
三、示例
a1.sinkgroups = g1
a1.sinkgroups.g1.sinks = k1 k2
a1.sinkgroups.g1.processor.type = failover
a1.sinkgroups.g1.processor.priority.k1 = 5
a1.sinkgroups.g1.processor.priority.k2 = 10
a1.sinkgroups.g1.processor.maxpenalty = 10000
Load Balancing Sink Processor
一、概述
- 提供了在多個sink之間實現負載均衡的能力
- 它維護了一個活動sink的索引列表
- 它支持輪詢或隨機方式的負載均衡,默認值是輪詢方式,可以通過配置指定
- 也可以通過實現AbstractSinkSelector接口實現自定義的選擇機制。
二、可配置項說明
配置項 | 說明 |
---|---|
processor.sinks | 綁定的sink |
processor.type | load_balance |
processor.selector | round_robin(輪叫調度)random(隨機) |
三、示例
01的配置示例:
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1 s2
a1.channels=c1
a1.sinkgroups=g1
#描述/配置a1的source1
a1.sources.r1.type=http
a1.sources.r1.port=8888
a1.sinkgroups.g1.sinks=s1 s2
a1.sinkgroups.g1.processor.type=load_balance
a1.sinkgroups.g1.processor.selector=round_robin
#輪叫調度算法(輪詢發送)
#描述sink
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=192.168.234.212
a1.sinks.s1.port=9999
a1.sinks.s2.type=avro
a1.sinks.s2.hostname=192.168.234.213
a1.sinks.s2.port=9999
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
a1.sinks.s2.channel=c1
02,03的配置示例:
#配置Agent a1 的組件
a1.sources=r1
a1.sinks=s1
a1.channels=c1
#描述/配置a1的source1
a1.sources.r1.type=avro
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=9999
#描述sink
a1.sinks.s1.type=logger
#描述內存channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100
#爲channel 綁定 source和sink
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1
事務機制
- Flume的事務機制與可靠性保證的實現,最核心的組件是Channel(通道)。如果沒有Channel組件,而緊靠Source與Sink組件是無從談起的
- 文件通道指的是將事件存儲到代理(Agent)本地文件系統中的通道。雖然要比內存通道慢一些,不過它卻提供了持久化的存儲路徑,可以應對大多數情況,它應該用在數據流中不允許出現缺口的場合
- File channel雖然提供了持久化,但是其性能較差,吞吐量會受到一定的限制。相反,memory channel則犧牲可靠性換取吞吐量。當然,如果機器斷電重啓,則無法恢復。在實際應用中,大多數企業都是選擇內存通道,因爲在通過flume收集海量數據場景下,使用FileChannel所帶來的性能下降是很大的甚至是無法忍受的。
一、put事務流程
- doPut:將批數據先寫入臨時緩衝區putList(Linkedblockingdequeue)
- doCommit:檢查channel內存隊列是否足夠合併。
- doRollback:channel內存隊列空間不足,回滾,等待內存通道的容量滿足合併
- putList就是一個臨時的緩衝區,數據會先put到putList,最後由commit方法會檢查channel是否有足夠的緩衝區,有則合併到channel的隊列
二、Take事務
- doTake:先將數據取到臨時緩衝區takeList(linkedBlockingDequeue)
- 將數據發送到下一個節點
- doCommit:如果數據全部發送成功,則清除臨時緩衝區takeList
- doRollback:數據發送過程中如果出現異常,rollback將臨時緩衝區takeList中的數據歸還給channel內存隊列。