一些需求是原生Flume無法滿足的,因此,基於開源的Flume我們增加了許多功能。 EventDeserializer的缺陷 Flume的每一個source對應的deserializer必須實現介面EventDeserializer,該介面定義了readEvent/readEvents方法從各種日誌 ...
一些需求是原生Flume無法滿足的,因此,基於開源的Flume我們增加了許多功能。
EventDeserializer的缺陷
Flume的每一個source對應的deserializer必須實現介面EventDeserializer,該介面定義了readEvent/readEvents方法從各種日誌源讀取Event。
flume主要支持兩種反序列化器:
(1)AvroEventDeserializer:解析Avro容器文件的反序列化器。對Avro文件的每條記錄生成一個flume Event,並將基於avro編碼的二進位記錄存入event body中。
(2)LineDeserializer:它是基於日誌文件的反序列化器,以“\n”行結束符將每行化分為一條日誌。
當日誌記錄本身被分割成多行時(比如堆棧異常日誌),就不能滿足這種要求。
針對這種情況,針對實際項目重新實現了日誌的解析。源碼參看https://github.com/bigdatafly/flume里的FileEventReader。
題外話,最近翻看了morphlines,日誌解析還可以用morphlines來實現。
另外,這裡還有個需要註意的地方:LineDeserializer有一個參數(maxLineLength)用於定義一個日誌行的最長字元數。如果某條日誌超過這個長度,將不再讀取。而一條日誌占據多行情況下,該值需要適當增大,因為像異常日誌的堆棧長度明顯比普通日誌長不少,這裡你可以設置為8192。
ExecSource的缺陷
ExecSource tail -F 適合固定文件日誌的讀取,最大問題不支持文件斷點續傳的功能。為此,在源碼的基礎上實現了flume-filetailsource。
源碼參看https://github.com/bigdatafly/flume里的FileTailSource.java
SpoolingDirSource的缺陷
用於監控文件目錄變化的,但是會有以下兩個問題:一是文件不能寫,只能讀。二是延遲比較高,需要等待日誌定期歸檔。項目中沒採用此方式。
這裡有個小插曲,由於之前已定製了source/sink的緣故。原以為deserializer也可以用同樣的方式進行定製。併在agent的deserializer配置中指定定製過的deserializer的完全限定名。但經過驗證後發現,這條路走不通,會報錯(貌似從flume官網上也找不到對deserializer定製的介紹)。因此,只能在源碼上進行擴展,然後編譯源碼,重新生成jar。
從源碼里你會發現為什麼在第三方包內擴展deserializer是行不通的。參看org.apache.flume.serialization.EventDeserializerType,你就會一目瞭然:
1 public enum EventDeserializerType { 2 LINE(LineDeserializer.Builder.class), 3 AVRO(AvroEventDeserializer.Builder.class), 4 OTHER(null); 5 private final Class<? extends EventDeserializer.Builder> builderClass; 6 EventDeserializerType(Class<? extends EventDeserializer.Builder> builderClass) { 7 this.builderClass = builderClass; 8 } 9 public Class<? extends EventDeserializer.Builder> getBuilderClass() { 10 return builderClass; 11 } 12 }
必須顯式在這裡定義deserializer的枚舉,然後指定其builder的Class實例,併在agent里的deserializer配置項中填寫你這裡的枚舉名稱才行。
系統的管理問題
Flume的啟動載入配置文件的方式有兩種:conf配置文件方式和Zookeeper方式。Flume對conf或者Zookeeper進行監控。當配置信息發生變化時,重新初始化配置參數,併進行重啟。目前系統,flume參數統一存儲在Zookeeper上。通過翻看源碼,發現解決這個問題需要重寫大量的源碼,任務巨大,目前還在思考結合實際情況如何巧妙的解決這個問題。
實際項目實施中,整個flume的架構,分為兩層agent和collector。
源碼參看https://github.com/bigdatafly/flume