Flume是一個分佈式、可靠、和高可用的海量日誌聚合的系統,支持在系統中定製各種數據發送方,用於收集數據;同時,Flume提供對數據進行簡單處理,並寫到各類數據接受方(可定製)的能力。html
(1) 可靠性node
當節點出現故障時,日誌可以被傳送到其餘節點上而不會丟失。Flume提供了三種級別的可靠性保障,從強到弱依次分別爲:end-to-end(收到數據agent首先將event寫到磁盤上,當數據傳送成功後,再刪除;若是數據發送失敗,能夠從新發送。),Store on failure(這也是scribe採用的策略,當數據接收方crash時,將數據寫到本地,待恢復後,繼續發送),Best effort(數據發送到接收方後,不會進行確認)。git
(2) 可擴展性github
Flume採用了三層架構,分別爲agent,collector和storage,每一層都可以水平擴展。其中,全部agent和collector由master統一管理,這使得系統容易監控和維護,且master容許有多個(使用ZooKeeper進行管理和負載均衡),這就避免了單點故障問題。web
(3) 可管理性shell
全部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等)。安全
flume的邏輯架構:服務器
正如前面提到的,Flume採用了分層架構:分別爲agent,collector和storage。其中,agent和collector均由兩部分組成:source和sink,source是數據來源,sink是數據去向。
Flume使用兩個組件:Master和Node,Node根據在Master shell或web中動態配置,決定其是做爲Agent仍是Collector。
agent的做用是將數據源的數據發送給collector。
Flume自帶了不少直接可用的數據源(source),如:
更多可參見這位朋友的整理:http://www.cnblogs.com/zhangmiao-chp/archive/2011/05/18/2050465.html
同時提供了不少sink,如:
更多可參見這位朋友的整理:http://www.cnblogs.com/zhangmiao-chp/archive/2011/05/18/2050472.html
collector的做用是將多個agent的數據彙總後,加載到storage中。
它的source和sink與agent相似。
數據源(source),如:
sink,如:
storage是存儲系統,能夠是一個普通file,也能夠是HDFS,HIVE,HBase,分佈式存儲等。
Master是管理協調agent和collector的配置等信息,是flume集羣的控制器。
在Flume中,最重要的抽象是data flow(數據流),data flow描述了數據從產生,傳輸、處理並最終寫入目標的一條路徑。
注:Flume框架對hadoop和zookeeper的依賴只是在jar包上,並不要求flume啓動時必須將hadoop和zookeeper服務也啓動。
部署flume在集羣上,按照以下步驟:
須要在集羣的每臺機器上部署Flume。
注意:flume集羣整個集羣的網絡環境要保證穩定,可靠,不然會出現一些莫名錯誤(好比:agent端發送不了數據到collector)。
$wget http://cloud.github.com/downloads/cloudera/flume/flume-distribution-0.9.4-bin.tar.gz $tar -xzvf flume-distribution-0.9.4-bin.tar.gz $cp -rf flume-distribution-0.9.4-bin /usr/local/flume $vi /etc/profile #添加環境配置 export FLUME_HOME=/usr/local/flume export PATH=.:$PATH::$FLUME_HOME/bin $source /etc/profile $flume #驗證安裝
對於master的選擇狀況,能夠在集羣上定義一個master,也能夠爲了提升可用性選擇多個節點作爲master。
Flume master數量的選擇原則:
分佈式的master可以繼續正常工做不會崩潰的前提是正常工做的master數量超過總master數量的一半。
Flume master 的做用主要有兩個:
site-specific設置對於flume節點和master經過在每個集羣節點的conf/flume-site.xml是可配置的,若是這個文件不存在,設置的屬性默認的在conf/flume-conf.xml中,在接下來的例子中,在flume的節點上設置master名,讓節點本身去尋找叫「master」的flume Master。
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>flume.master.servers</name> <value>master</value> </property> </configuration>
在多master的狀況下須要以下配置:
<property> <name>flume.master.servers</name> <value>hadoopmaster.com,hadoopedge.com,datanode4.com</value> <description>A comma-separated list of hostnames, one for each machine in the Flume Master.</description> </property> <property> <name>flume.master.store</name> <value>zookeeper</value> <description>How the Flume Master stores node configurations. Must be either 'zookeeper' or 'memory'.</description> </property> <property> <name>flume.master.serverid</name> <value>2</value> <description>The unique identifier for a machine in a Flume Master ensemble. Must be different on every master instance.</description> </property>
注意:flume.master.serverid 屬性的配置主要是針對master,集羣上Master節點的flume.master.serverid 必須是不能相同的,該屬性的值以0開始。
當使用agent角色時,你能夠經過添加下面的配置文件在flume-conf.xml中,來設置默認的collector主機:
<property> <name>flume.collector.event.host</name> <value>collector</value> <description>This is the host name of the default "remote" collector.</description> </property> <property> <name>flume.collector.port</name> <value>35853</value> <description>This default tcp port that the collector listens to in order to receive events it is collecting.</description> </property>
關於配置可參見:http://www.cnblogs.com/zhangmiao-chp/archive/2011/05/18/2050443.html。
集羣上節點啓動:
名字規則本身定義,方便記憶和動態配置便可(後續會有介紹動態配置)
關於flume shell 中的command參見:http://www.cnblogs.com/zhangmiao-chp/archive/2011/05/18/2050461.html
假設咱們目前部署的Flume集羣結構以下:
咱們想將A-F所在的機器的系統日誌收集到HDFS中,怎麼樣在flume shell中配置達到咱們的目的呢?
1. 設置邏輯節點(logical node)
$flume shell >connect localhost >help >exec map 192.168.0.1 agentA >exec map 192.168.0.2 agentB >exec map 192.168.0.3 agentC >exec map 192.168.0.4 agentD >exec map 192.168.0.5 agentE >exec map 192.168.0.6 agentF >getnodestatus 192.168.0.1 --> IDLE 192.168.0.2 --> IDLE 192.168.0.3 --> IDLE 192.168.0.4 --> IDLE 192.168.0.5 --> IDLE 192.168.0.6 --> IDLE agentA --> IDLE agentB --> IDLE agentC --> IDLE agentD --> IDLE agentE --> IDLE agentF --> IDLE >exec map 192.168.0.11 collector
這裏你也能夠打開web master界面查看。
2.啓動Collector的監聽端口
>exec config collector 'collectorSource(35853)' 'collectorSink("","")'#collector節點監聽35853端口過來的數據,這一部很是重要
登錄到collector服務器進行端口檢測
$netstat -nalp|grep 35853
若是在master中未進行上述配置,在collector上檢測不到此打開端口
3.設置各節點的source和sink
>exec config collector 'collectorSource(35853)' 'collectorSink("hdfs://namenode/flume/","syslog")' >exec config agentA 'tail("/tmp/log/message")' 'agentBESink("192.168.0.11")' #通過實驗,好像一個邏輯節點,最多隻能有一個source和sink.
>...
>exec config agentF 'tail("/tmp/log/message")' 'agentBESink("192.168.0.11")'
這時的配置狀況可從master web中一目瞭然,此時已經能夠達到咱們最初的目的了。
以上經過flume shell進行的動態配置,在flume master web中均可以進行,在此不作進一步說明。
高級配置其實就是在上述簡單配置中增長了如下幾個特性來保證系統更好的運行:
多Master的狀況在上面已經有過介紹,包括用途和master個數等。下面來簡單看一下Collector Chain,其實也很簡單,就是在動態配置時,使用agent*Chain來指定多個Collector來保證其日誌傳輸的可用性。看一下通常正式環境中flume的邏輯圖:
這裏agentA和agentB指向collectorA,若是CollectorA crach了,根據配置的可靠性級別agent會有相應的動做,咱們極可能爲了保障高效傳輸而沒有選擇E2E(即便是這種方式,Agent本地日誌累積過多依然是一個問題),通常會配置多個Collector,造成collector chain。
>exec config agentC 'tail("/tmp/log/message")' 'agentE2EChain("collectorB:35853","collectorA:35853")' >exec config agentD 'tail("/tmp/log/message")' 'agentE2EChain("collectorB:35853","collectorC:35853")'
這樣collectorB在出問題時:
上述節點有以下幾類:master、agent、collector、storage,針對每類節點咱們看一下高可用和有沒有可能引發性能瓶頸問題。
首先,storage層的失敗和collector層的失敗是同樣的,只要數據放不到最終的位置,就認爲節點是失敗的。咱們必定會根據收集數據的可靠性設定合適的傳輸模式,並且會根據咱們的配置,本身控制collector接收數據的狀況,collector的性能影響的是整個flume集羣的數據吞吐量,因此collector最好單獨部署,因此通常不用考慮高可用問題。
而後,agent層的失敗,Flume數據安全級別的配置主要Agent的配置上,Agent提供三種級別發送數據到collector:E2E、DFO、BF,在些不贅述。看一下一位大牛的總結:
agent節點監控日誌文件夾下的全部文件,每個agent最多監聽1024個文件,每個文件在agent的都會有一個相似遊標的東西,記錄監聽文件讀取的位置,這樣每次文件有新的記錄產生,那麼遊標就會讀取增量記錄,根據agent配置發送到collector的安全層級屬性有E2E,DFO。
若是是E2E的狀況那麼agent節點會首先把文件寫入到agent節點的文件夾下,而後發送給collector,若是最終數據最終成功存儲到storage層,那麼agent刪除以前寫入的文件,若是沒有收到成功的信息,那麼就保留信息。 若是agent節點出現問題,那麼至關於全部的記錄信息都消失了,若是直接從新啓動,agent會認爲日誌文件夾下的全部文件都是沒有監聽過的,沒有文件記錄的標示,因此會從新讀取文件,這樣,日誌就會有重複,具體恢復辦法以下 將agent節點上監聽的日誌文件夾下已經發送的日誌文件移出,處理完,故障從新啓動agent便可。 注:在agent節點失敗的狀況下,按照失敗的時間點,將時間點以前的數據文件移出,將flume.agent.logdir配置的文件夾清空,從新啓動agent。
最後,master失敗,master宕機,整個集羣將不能工做,在從新啓動集羣,將agent監聽的日誌文件夾下的全部文件移出,而後從新啓動master便可。在多master節點狀況下,只要集羣上正常工做的master大於總master數量的一半,集羣就能正常工做,那麼只要恢復其中宕機的master便可。
1.Flume在agent端採集數據的時候默認會在/tmp/flume-{user}下生成臨時的目錄用於存放agent本身截取的日誌文件,若是文件過大致使磁盤寫滿那麼agent端會報出 Error closing logicalNode a2-18 sink: No space left on device,因此在配置agent端的時候須要注意 <property> <name>flume.agent.logdir</name> <value>/data/tmp/flume-${user.name}/agent</value> </property> 屬性,只要保證flume在7*24小時運行過程agent端不會使該路徑flume.agent.logdir磁盤寫滿便可。
2. Flume在啓動時候會去尋找hadoop-core-*.jar的文件,須要修改標準版的hadoop核心jar包的名字 將hadoop-*-core.jar改爲hadoop-core-*.jar。
3.Flume集羣中的flume必須版本一致。不然會出現莫名其妙的錯誤。
4.Flume集羣收集的日誌發送到hdfs上創建文件夾的時間依據是根據event的時間,在源代碼上是Clock.unixTime(),因此若是想要根據日誌生成的時間來生成文件的話,須要對 com.cloudera.flume.core.EventImpl 類的構造函數 public EventImpl(byte[] s, long timestamp, Priority pri, long nanoTime, String host, Map<String, byte[]> fields)從新寫,解析數組s的內容取出時間,賦給timestamp。
注意:flume的框架會構造s內容是空的數組,用來發送相似簡單驗證的event,因此須要注意s內容爲空的時候timestamp的問題。
5.若是collector和agent不在一個網段的話會發生閃斷的現象,這樣的話,就會形成agent端不能傳送數據個collector因此,在部署agent和collector最好在一個網段。
6.若是在啓動master時出現:「試着啓動hostname,可是hostname不在master列表裏的錯誤「,這是須要檢查是否主機地址和hostname配置的正確與否。
7.在源端,有一個比較大的缺陷,在tail類的source,不支持,斷點續傳功能。由於重啓node後沒有記錄上次文件讀到的位置,從而沒辦法知道,下次再讀時,從什麼地方開始讀。 特別是在日誌文件一直在增長的時候。flume的source node掛了。等flume的source再次開啓的這段時間內,增長的日誌內容,就沒辦法被source讀取到了。 不過flume有一個execStream的擴展,能夠本身寫一個監控日誌增長狀況,把增長的日誌,經過本身寫的工具把增長的內容,傳送給flume的node。再傳送給sink的node。
之前文章中介紹過Scribe方案,給個人最直觀感覺就是:
下面董的博客中的一副對比圖: