原文鏈接:記Flume-NG一些注意事項
這里只考慮flume本身的一些東西,對於JVM、HDFS、HBase等得暫不涉及。。。。
一、關於Source:
1、spool-source:適合靜態文件,即文件本身不是動態變化的;
2、avro source可以適當提高線程數量來提高此source性能;
3、ThriftSource在使用時有個問題需要注意,使用批量操作時出現異常並不會打印異常內容而是"Thrift source %s could not append events to the channel.",這是因為源碼中在出現異常時,它並未捕獲異常而是獲取組件名稱,這是源碼中的一個bug,也可以說明thrift很少有人 用,否則這個問題也不會存在在很多版本中;
4、如果一個source對應多個channel,默認就是每個channel是同樣的一份數據,會把這批數據復制N份發送到N個channel中,所以如果某個channel滿了會影響整體的速度的哦;
5、ExecSource官方文檔已經說明是異步的,可能會丟數據哦,盡量使用tail -F,注意是大寫的;
二、關於Channel:
1、采集節點建議使用新的復合類型的SpillableMemoryChannel,匯總節點建議采用memory channel,具體還要看實際的數據量,一般每分鍾數據量超過120MB大小的flume agent都建議用memory channel(自己測的file channel處理速率大概是2M/s,不同機器、不同環境可能不同,這里只提供參考),因為一旦此agent的channel出現溢出情況,將會導致大 多數時間處於file channel(SpillableMemoryChannel本身是file channel的一個子類,而且復合channel會保證一定的event的順序的使得讀完內存中的數據后,再需要把溢出的拿走,可能這時內存已滿又會溢 出。。。),性能大大降低,匯總一旦成為這樣后果可想而知;
2、調整memory 占用物理內存空間,需要兩個參數byteCapacityBufferPercentage(默認是20)和byteCapacity(默認是JVM最大 可用內存的0.8)來控制,計算公式是:byteCapacity = (int)((context.getLong("byteCapacity", defaultByteCapacity).longValue() * (1 - byteCapacityBufferPercentage * .01 )) /byteCapacitySlotSize),很明顯可以調節這兩個參數來控制,至於byteCapacitySlotSize默認是100,將物理內 存轉換成槽(slot)數,這樣易於管理,但是可能會浪費空間,至少我是這樣想的。。。;
3、還有一個有用的參數"keep-alive"這個參數用來控制channel滿時影響source的發送,channel空時影響sink 的消費,就是等待時間,默認是3s,超過這個時間就甩異常,一般不需配置,但是有些情況很有用,比如你得場景是每分鍾開頭集中發一次數據,這時每分鍾的開 頭量可能比較大,后面會越來越小,這時你可以調大這個參數,不至於出現channel滿了得情況;
三、關於Sink:
1、avro sink的batch-size可以設置大一點,默認是100,增大會減少RPC次數,提高性能;
2、內置hdfs sink的解析時間戳來設置目錄或者文件前綴非常損耗性能,因為是基於正則來匹配的,可以通過修改源碼來替換解析時間功能來極大提升性能,稍后我會寫一篇文章來專門說明這個問題;
3、RollingFileSink文件名不能自定義,而且不能定時滾動文件,只能按時間間隔滾動,可以自己定義sink,來做定時寫文件;
4、hdfs sink的文件名中的時間戳部分不能省去,可增加前綴、后綴以及正在寫的文件的前后綴等信息;"hdfs.idleTimeout"這個參數很有意義,指 的是正在寫的hdfs文件多長時間不更新就關閉文件,建議都配置上,比如你設置了解析時間戳存不同的目錄、文件名,而且rollInterval=0、 rollCount=0、rollSize=1000000,如果這個時間內的數據量達不到rollSize的要求而且后續的寫入新的文件中了,就是一直 打開,類似情景不注意的話可能很多;"hdfs.callTimeout"這個參數指的是每個hdfs操作(讀、寫、打開、關閉等)規定的最長操作時間, 每個操作都會放入"hdfs.threadsPoolSize"指定的線程池中得一個線程來操作;
5、關於HBase sink(非異步hbase sink:AsyncHBaseSink),rowkey不能自定義,而且一個serializer只能寫一列,一個serializer按正則匹配多個 列,性能可能存在問題,建議自己根據需求寫一個hbase sink;
6、avro sink可以配置failover和loadbalance,所用的組件和sinkgroup中的是一樣的,而且也可以在此配置壓縮選項,需要在avro source中配置解壓縮;
四、關於SinkGroup:
1、不管是loadbalance或者是failover的多個sink需要共用一個channel;
2、loadbalance的多個sink如果都是直接輸出到同一種設備,比如都是hdfs,性能並不會有明顯增加,因為sinkgroup是 單線程的它的process方法會輪流調用每個sink去channel中take數據,並確保處理正確,使得是順序操作的,但是如果是發送到下一級的 flume agent就不一樣了,take操作是順序的,但是下一級agent的寫入操作是並行的,所以肯定是快的;
3、其實用loadbalance在一定意義上可以起到failover的作用,生產環境量大建議loadbalance;
五、關於監控monitor:
1、監控我這邊做得還是比較少的,但是目前已知的有以下幾種吧:cloudera manager(前提是你得安裝CDH版本)、ganglia(這個天生就是支持的)、http(其實就是將統計信息jmx信息,封裝成json串,使用 jetty展示在瀏覽器中而已)、再一個就是自己實現收集監控信息,自己做(可以收集http的信息或者自己實現相應的接口實現自己的邏輯,具體可以參考 我以前的博客);
2、簡單說一下cloudera manager這種監控,最近在使用,確實很強大,可以查看實時的channel進出數據速率、channel實時容量、sink的出速率、source 的入速率等等,圖形化的東西確實很豐富很直觀,可以提供很多flume agent整體運行情況的信息和潛在的一些信息;
六、關於flume啟動:
1、flume組件啟動順序:channels——>sinks——>sources,關閉順序:sources——>sinks——>channels;
2、自動加載配置文件功能,會先關閉所有組件,再重啟所有組件;
3、關於AbstractConfigurationProvider中的Map<Class<? extends Channel>, Map<String, Channel>> channelCache這個對象,始終存儲着agent中得所有channel對象,因為在動態加載時,channel中可能還有未消費完的數據,但是需要對channel重新配置,所以用以來緩存channel對象的所有數據及配置信息;
4、通過在啟動命令中添加 "no-reload-conf"參數為true來取消自動加載配置文件功能;
七、關於interceptor:
請看我的關於這個組件的博客,傳送門;
八、關於自定義組件:sink、source、channel:
1、channel不建議自定義哦,這個要求比較高,其他倆都是框架式的開發,往指定的方法填充自己配置、啟動、關閉、業務邏輯即可,以后有機會單獨寫一篇文章來介紹;
2、關於自定義組件請相信github,上面好多好多好多,可以直接用的自定義組件....;
九、關於Flume-NG集群網絡拓撲方案:
1、在每台采集節點上部署一個flume agent,然后做一到多個匯總flume agent(loadbalance),采集只負責收集數據發往匯總,匯總可以寫HDFS、HBase、spark、本地文件、kafka等等,這樣一般 修改會只在匯總,agent少,維護工作少;
2、采集節點沒有部署flume agent,可能發往mongo、redis等,這時你需要自定義source或者使用sdk來將其中的數據取出並發往flume agent,這樣agent就又可以充當“采集節點”或者匯總節點了,但是這樣在前面相當於加了一層控制,就又多了一層風險;
3、由於能力有限,其它未知,上面兩種,第一種好些,這里看看美團的架構———— 傳送門 ;
東西比較簡單,容易消化。