目錄
一、Flume 的可恢復性
靠 Channel。推薦使用 FileChannel,事件持久化在本地文件系統裏(性能較差)。
二、Flume 架構
1、Client
生產數據,運行在一個獨立線程。
2、Event
Flume 將數據表示成 Event,數據結構很簡單,具有一個主題和一個報頭的集合。事件的主題是一個字節數組,通常通過 Flume 傳送的負載。報頭被稱爲一個 map,其中有字符串 key 和字符串 value,報頭不是用來傳輸數據的,而是爲了路由和跟蹤發送事件的優先級和嚴重性。報頭也可以用給事件增加事件 ID 或者 UUID。每個事件本質上必須是一個獨立的記錄,而不是記錄的一部分。這也要求每個事件要適應 Flume Agent JVM 的內存,如果使用 File Channel 應該有足夠的硬盤空間來支持。如果數據不能表示多個獨立記錄,Flume 可能不適用這樣的案例。
3、Agent
Flume 運行的核心是 Agent,Agent 本身是一個 Java 進程,也是最小獨立運行的單位,運行在日誌收集節點 Agent 是一個完整的數據收集工具,含有三個核心組件,分別是 Source、Channel、Sink,Flume 基於數據流進行設計,數據流由事件(Event)貫穿始終。事件作爲 Flume 的基本數據單位,攜帶日誌數據(以字節數組形式)並且攜帶頭信息,由 Agent 外部的數據源生成。
4、Source
Source 是從一些生產數據的應用中接收數據的活躍組件。也有自己生產數據的 Source,不過通常用於測試目的。Source 可以監聽一個或多個網絡端口,用於接收數據或者可以從本地文件系統讀取數據,每一個 Source 必須至少連接一個 Channel。基於一些標準,一個 Source 可以寫入多個 Channel,複製事件到所有或者部分的 Channel。Flume 提供了很多內置的 Source,支持 avro,log5j,syslog 和 http port(body 爲 json 格式)。
Source 類型 | 說明 |
---|---|
Avro | 支持 Avro 協議,即 Avro RPC,內置支持 |
Thrift | 支持 Thrift 協議,內置支持 |
Exec | 基於 Unix 的命令在標準輸出上產生數據 |
JMS | 從 JMS 系統中讀取數據 |
Spooling Directory | 監控指定目錄內數據變化 |
Netcat | 監控某個端口,將流經端口的文本行數據作爲 Event 輸入 |
Sequence Gennerator | 序列生產器的數據源,生產序列數據 |
Syslog | 讀取 syslog 數據,產生 Event,支持 UDP 和 TCP 協議 |
HTTP | 基於 HTTP POST 或者 GT 方式的數據源,支持 JSON 等格式 |
Legacy | 兼容 Flume OG 中的 Source(0.9.x 版本) |
4.1 avro source
屬性名 | 默認值 | 說明 |
---|---|---|
channels | - | |
type | - | 類型名稱 avro |
bind | - | 需要監聽的主機名或者 IP |
port | - | 需要監聽端口 |
threads | - | 工作線程最大線程數 |
selector.type | 複製還是多路複製 | |
selector.* | 依賴於 selector.type 的值 | |
interceptors | - | 空格分隔攔截器地址 |
interceptors.* | ||
compression-type | none | 壓縮類型必須和 AvroSource 值相同 |
ssl | false | 是否啓用 ssl 加密同時還要配置 keystore 和 keystore-password |
keystore | - | 爲 SSL 提供 Java 祕鑰文件所在路徑 |
keystore-password | - | 爲 SSL 提供的 Java 祕鑰文件密碼 |
keystore-type | JKS | 祕鑰庫類型可以是“JKS”或者“PKCS12” |
exclude-protocols | SSLv3 | 空格指定分開的列表,用來指定在 SSL/TLS 協議中排除。SSLv3 將總是被排除除了所指定的協議 |
ipFilter | false | 如果需要爲 netty 開啓 ip 過濾,將此選項設置爲 true |
ipFilterRules | - | 配 netty 的 ip 過濾設置表達式規則 |
下面是官網提供的例子:
a1.sources = r1
a1.channels = c1
a1.sources.r1.type = avro
a1.sources.r1.bind = 10.10.10.10
a1.sources.r1.port = 4545
a1.sources.r1.channels = c1
4.2 exec source
屬性名 | 默認值 | 說明 |
---|---|---|
channels | - | |
type | - | 類型名稱 exec |
command | - | 要執行的命令 |
shell | - | 用於執行命令的 shell |
restartThrottle | 1000 | 毫秒爲單位,用於聲明等待多久後嘗試重試命令 |
restart | false | 如果 cmd 掛了是否重啓 cmd |
logStdErr | false | 無論是否是標準錯誤都應該被記錄 |
batchSize | 20 | 同時發送到通道中的最大行數 |
batchTimeout | 3000 | 如果緩衝區沒有滿,經過多長時間發送數據 |
selector.type | 複製還是多路複製 | |
selector.* | 依賴於 selector.type 的值 | |
interceptors | - | 空格分隔的攔截器列表 |
interceptors.* |
下面是官網提供的例子:
a1.sources = r1
a1.channels = c1
a1.sources.r1.type = exec
a1.sources.r1.command = for i in /path/*.txt; do cat $i; done
a1.sources.r1.shell = /bin/bash -c
a1.sources.r1.channels = c1
5、Channel
Channel 一般地被認爲是被動的組件,負責緩存 Agent 已經接收但尚未寫出到另外一個 Agent 或者存儲系統的數據,雖然他們可以爲了清理或者垃圾回收運行自己的線程。Channel 的行爲很像隊列,Source 把數據寫入到他們,Sink 從他們中讀取數據,多個 Source 可以安全地寫入到相同的 Channel,並且多個 Sink 可以從相同的 Channel 進行讀取,一個 Sink 只能從一個 Channel 進行讀取,它可以保證只有一個 Sink 會從 Channel 讀取一個指定的事件。
Channel 類型 | 說明 |
---|---|
Memory | Event 數據存儲在內存中 |
JDBC | Event 數據存儲在持久化存儲中 |
File | Event 數據存儲在磁盤文件中 |
Spilable Memory | Event 數據存儲在內存和硬盤上,當內存隊列已滿,將持久化到磁盤文件(不建議生產環境使用) |
Pseudo Transaction | 測試用途 |
Customm | 自定義 |
5.1 memory channel
屬性名稱 | 默認值 | 說明 |
---|---|---|
type | - | 類型名稱 memory |
capacity | 100 | 存儲在 channel 中的最大容量 |
transactionCapacity | 100 | 從一個 source 中去或者給一個 sink,每個失誤中的最大事件數 |
keep-alive | 3 | 對於添加或者刪除一個事件超時的秒鐘 |
byteCapacityBufferPercentage | 20 | 定義Channle中Event所佔的百分比,需要考慮在Header中的數據。 |
byteCapacity | see description | 最大內存所有事件允許的總字節數 |
下面是官網提供的例子:
a1.channels = c1
a1.channels.c1.type = memory
a1.channels.c1.capacity = 10000
a1.channels.c1.transactionCapacity = 10000
a1.channels.c1.byteCapacityBufferPercentage = 20
a1.channels.c1.byteCapacity = 800000
5.2 file channel
注意默認情況下,File Channel 使用檢查點(checkpointDir)和在用戶目錄(dataDirs)上指定的數據目錄。所以在一個 agent 下面啓動多個 File Channel 實例,只會有一個 File channel 能鎖住文件目錄,其他的都將初始化失敗。因此,有必要提供明確的路徑的所有已配置的通道,同時考慮最大吞吐率,檢查點與數據目錄最好是在不同的磁盤上。
屬性名稱 | 默認值 | 說明 |
---|---|---|
type | - | 類型名稱 file |
checkpointDir | ~/.flume/file-channel/checkpoint | checkp 所在目錄 |
dataDirs | ~/.flume/file-channel/data | 以逗號分隔的用於存儲日誌文件的目錄列表。在不同的磁盤上使用多個目錄可以提高文件通道性能 |
下面是官網提供的例子:
a1.channels = c1
a1.channels.c1.type = file
a1.channels.c1.checkpointDir = /mnt/flume/checkpoint
a1.channels.c1.dataDirs = /mnt/flume/dat
6、Sink
連續輪詢各自的 Channel 來讀取和刪除事件,Sink 將事件提送到下一階段,並且(RPC Sink 的情況下)活到最終目的地。一旦下一階段或者目的地中的數據是安全的,Sink 通過事務提交通知 Channel,可以從 Channel 中刪除這些事件。
Sink 類型 | 說明 |
---|---|
HDFS | 數據寫入到 HDFS |
Hbase | 數據寫入到 Hbase |
Logger | 數據直接控制檯輸出 |
Avro | 數據被轉換成 Avro Event,然後發送到配置的 RPC 端口上 |
IRC | 數據在 IRC 上進行回收 |
File Roll | 數據存儲到本地文件系統 |
Null | 丟棄所有數據 |
Morphine Solor | 數據發送到 Solr 搜索服務器(集羣) |
ElasticSearch | 數據發送到 ElasticSearch 搜索服務器(集羣) |
Custome sink | 自定義 |
6.1 hdfs sink
屬性名稱 | 默認值 | 說明 |
---|---|---|
type | - | 類型名稱 hdfs |
hdfs.path | - | 寫入 hdfs 的路徑,需要包含文件系統表示,如:hdfs://namenode/flume/webdata/ 可以使用 flume 提供日期及 %{host} 表達式 |
hdfs.filePrefix | FlumeData | 寫入 hdfs 的文件名前綴,可以使用 flume 提供的日期及 %{host} 表達式 |
hdfs.fileSuffix | - | 寫入 hdfs 文件名後綴,如:.lzo、.log |
hdfs.inUsePrefix | - | 臨時文件名前綴,hdfs sink 會先往目標目錄中寫臨時文件再根據相關規則重命名成最終文件 |
hdfs.inUseSuffix | .tmp | 臨時文件的後綴名 |
hdfs.rollInterval | 30 | hdfs sink間隔多長將臨時文件滾動成最終目標文件,單位:秒;如果設置成0,則表示不根據時間來滾動文件;注:滾動(roll)指的是,hdfs sink將臨時文件重命名成最終目標文件,並新打開一個臨時文件來寫入數據 |
hdfs.rollSize | 1024 | 當臨時文件達到該大小(單位:bytes)時,滾動成目標文件;如果設置成 0,則表示不根據臨時文件大小來滾動文件 |
hdfs.rollCount | 10 | 當 events 數據達到該數量時候,將臨時文件滾動成目標文件;如果設置成 0,則表示不根據 events 數據來滾動文件 |
hdfs.idleTimeout | 0 | 當目前被打開的臨時文件在該參數指定的時間(秒)內,沒有任何數據寫入,則將該臨時文件關閉並重命名成目標文件 |
hdfs.batchSize | 100 | 每個批次刷新到 HDFS 上的 events 數量 |
hdfs.codeC | - | 文件壓縮格式,包括:gzip, bzip2, lzo, lzop, snappy |
hdfs.fileType | SequenceFile | 文件格式 包括:SequenceFile, DataStream ,CompressedStream,當使用 DataStream 的時候,文本不會被壓縮,不需要設置 hdfs.codeC,當使用 CompressedStream 的時候必須設置一個正確的 hdfs.codeC 的值 |
hdfs.maxOpenFile | 5000 | 最大允許打開的 HDFS 文件數,當打開的文件數達到該值,最早打開的文件將會被關閉 |
hdfs.minBlockReplicas | - | 寫入 HDFS 文件塊的最小副本數,該參數會影響文件的滾動配置,一般將該參數設置成 1,纔可以按照配置正確滾動文件 |
hdfs.writeFormat | Writable | 寫入 sequence 文件的格式。包括:Text、Writable(默認) |
hdfs.callTimeout | 10000 | 執行 HDFS 操作的超時時間(單位:毫秒) |
hdfs.threadsPoolSize | 10 | hhdfs sink 啓動的操作 HDFS的線程數 |
hdfs.rollTimerPoolSize | 1 | hdfs sink 啓動的根據時間滾動文件的線程數 |
hdfs.kerberosPrincipal | - | HDFS 安全認證 kerberos配置 |
hdfs.kerberosKeytab | - | HDFS 安全認證 kerberos配置 |
hdfs.proxyUser | 代理用戶 | |
hdfs.round | false | 是否啓用時間上的“捨棄”,這裏的“捨棄”類似於“四捨五入”後面在介紹。如果啓用,則會很影響除了除了 %t 的其他所有時間的表達式 |
hdfs.roundValue | 1 | 時間上進行捨棄的值 |
hdfs.roundUnit | second | 時間上進行”捨棄”的單位,包含:second,minute,hour |
hdfs.timeZone | Local Time | 時區 |
hdfs.useLocalTimeStamp |
false | 是否使用當地時間 |
hdfs.colseTries | 0 | hdfs sink 關閉文件的嘗試次數;如果設置爲 1,當一次關閉文件失敗後,hdfs sink 將不會在嘗試關閉文件,這個爲未關閉的文件,將會一直留在那,並且時打開狀態,設置爲 0,當一次關閉失敗後,hdfs sink 會繼續嘗試下一次關閉,直到成功 |
hdfs.retryInterval | 180 | hdfs sink 嘗試關閉文件的時間間隔,如果設置爲 0,表示不嘗試,相當於將 hdfs.closeTries 設置爲 1 |
serializer | TEXT | 列化類型。其他的還有:avro_event 或者是實現了 EventSerializer.Builder 的類名 |
serializer.* |
下面是官網提供的例子:
a1.channels = c1
a1.sinks = k1
a1.sinks.k1.type = hdfs
a1.sinks.k1.channel = c1
a1.sinks.k1.hdfs.path = hdfs://namenode/flume/%y-%m-%d/%H%M/%S
a1.sinks.k1.hdfs.filePrefix = events-
a1.sinks.k1.hdfs.round = true
a1.sinks.k1.hdfs.roundValue = 10
a1.sinks.k1.hdfs.roundUnit = minute
6.2 avro sink
avro sink 主要用於 flume 分層結構。flume event 發送給這個 sink 的事件都會轉換成 avro 事件,發送到配置好的 avro 主機和端口上。這些事件可以批量傳輸給通道。
屬性名稱 | 默認值 | 說明 |
---|---|---|
type | - | 類型名稱 avro |
hostname | - | 要綁定到的主機名或 IP 地址 |
port | - | 監聽端口 |
下面是官網提供的例子:
a1.channels = c1
a1.sinks = k1
a1.sinks.k1.type = avro
a1.sinks.k1.channel = c1
a1.sinks.k1.hostname = 10.10.10.10
a1.sinks.k1.port = 4545
6.3 hive sink
屬性名稱 | 默認值 | 說明 |
---|---|---|
type | - | 類型名稱 hive |
hive.metastore | - | Hive metastore URI (eg thrift://a.b.com:9083 ) |
hive.database | - | Hive database name |
hive.table | - | Hive table name |
hive.partition | - | Hive 分區,逗號分隔的分區值列表,用於標識要寫入的分區,可能包含轉義序列 |
hive.txnsPerBatchAsk | 100 | Hive 將流式客戶端(如 Flume)授予一批事務而不是單筆事務。此設置配置每批處理的事務數。單個批次中來自所有事務的數據最終存儲在單個文件中。Flume 將在批處理的每個事務中最多寫入一個 batchSize 事件。此設置與 batchSize 結合使用,可以控制每個文件的大小。請注意,最終,Hive將透明地將這些文件壓縮爲更大的文件。 |
heartBeatInterval | 240 | (單位:秒)發送給 Hive 的連續心跳檢查的間隔,以防止未使用的事務過期。將此值設置爲 0 以禁用心跳。 |
autoCreatePartitions | true | Flume 將自動創建必要的 Hive 分區以流式傳輸 |
batchSize | 15000 | 單個 Hive 事務中寫入 Hive 的最大事件數 |
maxOpenConnections | 500 | 僅允許此數量的打開連接。如果超過此數量,則關閉最近最少使用的連接。 |
callTimeout | 10000 | (單位:毫秒)Hive 和 HDFS I / O 操作的超時時間,例如打開、寫入、提交、中止。 |
timeZone | Local Time | 解析分區中轉義序列的時區的名稱。例如America / Los_Angeles。 |
useLocalTimeStamp | false | 替換轉義序列時,請使用本地時間(而不是事件標頭中的時間戳) |
round | false | 是否啓用時間上的“捨棄”,這裏的“捨棄”類似於“四捨五入”後面在介紹。如果啓用,則會很影響除了除了 %t 的其他所有時間的表達式。 |
roundValue | 1 | 時間上進行捨棄的值 |
roundUnit | minute | 時間上進行”捨棄”的單位,包含:second,minute,hour |
serializer | 序列化器負責從事件中解析出字段並將它們映射到配置單元表中的列,選擇取決於事件中數據的格式,支持格式 DELIMITED、JSON | |
serializer.delimiter | , | (類型:string)傳入數據中的字段定界符。要使用特殊字符,請用雙引號將它們括起來,例如“ \ t” |
serializer.fieldnames | - | 從輸入字段到配置單元表中的列的映射。指定爲 Hive 表列名稱的逗號分隔列表(不包含空格),以其出現的順序標識輸入字段。要跳過字段,請保留未指定的列名。 |
serializer.serdeSeparator | Ctrl-A | (類型:character)自定義基礎 Serde 使用的分隔符。如果 serializer.fieldnames 中的字段與表列的順序相同,serializer.delimiter 與 serializer.serdeSeparator 相同,並且 serializer.fieldnames 中的字段數小於或等於表數,則可以提高效率,因爲傳入事件主體中的字段不需要重新排序以匹配表列的順序。對特殊字符(如“ \ t”)使用單引號,確保輸入字段不包含此字符。注意:如果 serializer.delimiter 是單個字符,則最好將其設置爲相同字符 |
下面是官網提供的例子:
## Example Hive table :
create table weblogs ( id int , msg string )
partitioned by (continent string, country string, time string)
clustered by (id) into 5 buckets
stored as orc;
## Example for agent named a1:
a1.channels = c1
a1.channels.c1.type = memory
a1.sinks = k1
a1.sinks.k1.type = hive
a1.sinks.k1.channel = c1
a1.sinks.k1.hive.metastore = thrift://127.0.0.1:9083
a1.sinks.k1.hive.database = logsdb
a1.sinks.k1.hive.table = weblogs
a1.sinks.k1.hive.partition = asia,%{country},%y-%m-%d-%H-%M
a1.sinks.k1.useLocalTimeStamp = false
a1.sinks.k1.round = true
a1.sinks.k1.roundValue = 10
a1.sinks.k1.roundUnit = minute
a1.sinks.k1.serializer = DELIMITED
a1.sinks.k1.serializer.delimiter = "\t"
a1.sinks.k1.serializer.serdeSeparator = '\t'
a1.sinks.k1.serializer.fieldnames =id,,msg
6.4 sink 轉義符的支持
注意:對於所有與時間相關的轉義序列,事件的頭中必須存在一個鍵爲 “timestamp” 的頭(除非 useLocalTimeStamp 設置爲 true)。一種自動添加的方法是使用 TimestampInterceptor。
轉義符 | 說明 |
---|---|
%{host} | 支持任意頭名稱。Substitute value of event header named “host”. Arbitrary header names are supported. |
%t | Unix時間(毫秒) |
%a | locale’s short weekday name (Mon, Tue, ...) |
%A | locale’s full weekday name (Monday, Tuesday, ...) |
%b | locale’s short month name (Jan, Feb, ...) |
%B | locale’s long month name (January, February, ...) |
%c | locale’s date and time (Sun Apr 26 18:44:02 CST 2020) |
%d | day of month (01) 每月中的第幾天 |
%D | date; same as %m/%d/%y |
%H | hour (00..23) |
%I | hour (01..12) |
%j | day of year (001..366) 一年中的第幾天 |
%k | hour ( 0..23) |
%m | month (01..12) |
%M | minute (00..59) |
%p | locale’s equivalent of am or pm |
%s | seconds since 1970-01-01 00:00:00 UTC |
%S | second (00..59) |
%y | last two digits of year (00..99) 年的後兩位 |
%Y | year (2010) |
%z | +hhmm numeric timezone (for example, -0400) |