Flume 系列 (二) 結構及運行原理

Flume結構及運行原理
一、Flume 特點
flume是一個分佈式、可靠、和高可用的海量日誌採集、聚合和傳輸的系統。支持在日誌系統中定製各類數據發送方,用於收集數據;同時,Flume提供對數據進行簡單處理,並寫到各種數據接受方(比如文本、HDFS、Hbase等)的能力 ,關於flume介紹,可以參考另外篇博文《Flume  初識》

二、Flume 概念及結構
Event: flume內部的數據單元,包含兩部分,一個頭結點,一個body結點,頭結點是一個Map<String, String>,部署的agent結點可以通過現有的Interceptor或者自定義Interceptor往消息頭裏放置數據,如ip,hostname等標識消息來源於哪臺服務器,event在flume內部做流轉,是數據傳輸的載體
Agent: 一個獨立的Flume進程,包含組件Source、 Channel、 Sink。
 
Source: 是數據的收集端,負責將數據捕獲後進行特殊的格式化,將數據封裝到事件(event) 裏,然後將事件推入Channel中。 Flume提供了很多內置的Source, 支持 Avro, log4j, syslog 和 http post(body爲json格式)。可以讓應用程序同已有的Source直接打交道,如AvroSource, SyslogTcpSource,Directory Source。 
flume支持多種數據來源,如taildir監控一個文件的變化,spollDir監控一個文件夾的變化,jmsSource接收jms消息等,最常用的avroSource是構成flume分層架構的基礎,source是一個接口,flume提供了多種消息接入方式,在sourceType枚舉類中都有詳細列出,特殊說明下,由於flume是面向接口編程,其中有一個Other的枚舉,是佔位符,使用者可以自定義source源,只要求在flume啓動的時候可以加載到這個類即可(底層是通過反射獲取到class的實例的)
Channel: 是一種短暫的存儲容器,它將從source處接收到的event格式的數據緩存起來,直到它們被sinks消費掉,它在source和sink間起着一共橋樑的作用,channal是一個完整的事務,這一點保證了數據在收發的時候的一致性. 並且它可以和任意數量的source和sink鏈接. 支持的類型有: JDBC channel , File System channel , Memort channel等.
flume是基於pipeline的模式,channel的存在豐富了flume的數據傳播途徑,channel可以再source和sink之間做緩衝,動態調節數據的收集及發送(內部有一個xxxCounter會沒接收到一個event或者發送一個event都會做記錄),緩衝source和sink之間的壓力,其二channel可以關聯多個source,如一個source可以按照配置選擇的將數據複製到各個管道,或者按照消息頭自動分發到指定的管道,一個channel可以接多個sink,這個實現了同一份數據的多發發送池,實現了數據的複用及負載均衡等功能,channel內部流轉的數據載體是event,flume channel支持多種數據緩衝實現方式,如fileChannel:用一個文件做數據緩存、memoryChannel:使用內存緩存,底層實現是一個LinkedBlockingDeque,一個雙向阻塞列表,具體可參見ChannelType
Sink從Channel中取出事件,然後將數據發到別處,可以向文件系統、數據庫、 hadoop存數據, 也可以是其他agent的Source。在日誌數據較少時,可以將數據存儲在文件系統中,並且設定一定的時間間隔保存數據。
flume的數據發送池Sink,主要負責數據的發送,從channel接收到event,然後發送到指定的數據接收方,flume提供多種sink實現,具體可參見SinkType,常用的有:loggerSink:這個主要用於flume的部署調試,它會將接收到的event事件直接用log4j輸出出來,RollingFileSink:這個sink主要是將接收到的日誌文件序列化到一個文件目錄中,所以需要配置文件的地址,切分文件的頻率等,avroSink:這個是flume分層架構中最常用的sink,一般和avroSource配對使用,avro是apache的一個子項目,用於數據的序列化,使用avroSource及avroSink時,需要在avroSource的agent節點服務器上監聽一個端口,avroSink的agent把接收到的數據發送到該ip、port上即完成了flume的分層部署,avro僅是一個數據序列化工具,底層實現由一個RpcClient的東東來將數據在這source和sink之間傳輸(可以留一下啓動日誌,會自動創建一個RpcClient),當然,flume的編碼是按照面向接口來的,所以和source一樣支持自定義的sink
Flume提供了大量內置的Source、Channel和Sink類型。不同類型的Source,Channel和Sink可以自由組合。組合方式基於用戶設置的配置文件,非常靈活。

三、Flume 運行原理
flume提供了很多輔助類用於驅動、分發內部event及整個flume系統的運轉,基本如下
配置領域:
AgentConfiguration:這個看名字就知道是flume的配置元素領域內的東西,是的,使用者在flume-conf.properties中配置的數據解析成AgentConfiguration,是配置文件到面向對象的一個抽象
AbstractConfigurationProvider:該類看名字就是一個抽象的配置Provider類,內部有一個很重要的方法就是:getConfiguration(),該方法中通過如下幾個private方法來加載flume的channel、source、sink、sinkGroups並將它們關聯起來
        loadChannels(agentConf, channelComponentMap);
        loadSources(agentConf, channelComponentMap, sourceRunnerMap);
        loadSinks(agentConf, channelComponentMap, sinkRunnerMap);
flume還支持動態加載,PollingPropertiesFileConfigurationProvider(AbstractConfigurationProvider的一個具體實現)在flume啓動的時候會啓動一個線程FileWatcherRunnable,監控flume的配置文件變化,配置文件內部加載用的是google的EventBus來驅動的
驅動領域:
flume的source有如下兩個子接口:PollableSource和EventDrivenSource,前者需要自己去輪循的訪問數據源,當前是否可以加載到數據,如果有則加載進來轉換成flume的event,實現類有taildir、spollDir、jsmSource、kafkaSource等,該接口新增了一個process方法用於輪循調用,後者是一個事件驅動的Source,該接口不需要主動去訪問數據源,僅需要接收數據推動過來的event並轉換成flume的event即可,實現類有:scribeSource(該數據源用來打通Facebook的scribe數據收集工具)、AvroSource等
SourceRunner:由於這兩個source的存在,所以所以flume提供了兩個sourceRunner來驅動source的運行,分別是PollableSourceRunner和EventDrivenSourceRunner,前者啓動時自動啓動一個PollingRunner線程用於定時輪循process方法
channelProcessor:該類用於source到channel之間的數據發送,實現了一個source可以關聯到多個channel,簡單點如這2個接口,source的定義:setChannelProcessor(ChannelProcessor channelProcessor)指定一個ChannelProcessor ,ChannelProcessor 關聯到一個final的ChannelSelector,selector關聯到Channel:setChannels(List<Channel> channels)
ChannelProcessor:關聯到指定的ChannelSelector,ChannelSelector提供了兩種selector方式,ReplicatingChannelSelector:將source的event複製到各個channel中,MultiplexingChannelSelector:根據頭結點的header信息自動路由到對應的Channel中Transaction及BasicTransactionSemantics
flume的Channel內部保證一個event的發送在一個事務完成,如果發送失敗或者接收失敗則回滾,當成功時才從channel中刪除掉該event
SinkProcessor:用過選擇要發送的sink,什麼意思呢?該類有兩個實現:
LoadBalancingSinkProcessor:負載均衡方式:提供了roud_bin算法和random算法、以及固定order算法的實現方式,將Channel中的event發送到多個sink上
FailoverSinkProcessor:可以實現實現failover功能,具體流程類似LoadBalancingSinkProcessor,區別是FailoverSinkProcessor維護了一個PriorityQueue,用來根據權重選擇sink
SinkRunner:該類用於驅動一個sink,啓動是內部開了一個線程PollingRunner,定時的調用SinkProcessor
上述是所有的核心概念及代碼作用,下面描述下flume的運行流程:
1.系統啓動時通過配置領域可以按照客戶定義的配置加載一個flume
2.SourceRunner和SinkProcessor同時啓動,一個往Channel中生產event,一個從Channel中消費event,內部是一個生產者消費者模式
3.通過一些輔助類,實現Channel到source及sink的多路分發及分層架構

參考博文:https://www.cnblogs.com/zhangyinhua/p/7803486.html
https://www.cnblogs.com/adealjason/p/6240122.html
 

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