借鑒開源框架自研日志收集系統
項目背景
公司項目需要將分布在多臺機器中的日志統一收集管理。筆者先后使用logstash,flume等開源項目。并最終自研一套基于Java語言的日志收集系統 Bloodhound。以下從項目關注的角度對開源系統與自研進行分析。
1 開源日志收集系統特征
Logstash 和 Flume 都是很成熟的日志收集平臺,結構清晰,插件豐富,文檔簡明易懂,示例代碼非常多。其中Logstash 側重對字段的預處理,Flume 側重不同的網絡拓撲中日志的傳遞,通過Agent打通各個網絡結點。
2 關于日志收集系統的考量
開發語言的選擇
公司的開發團隊主要集中在 Java,Python。而 Logstash 的插件使用 Ruby,從團隊角度,不太具備擴展性。在使用 logstash 增加一個插件比較痛苦,同時幾個月使用下來,感覺性能偏低,啟動時較慢。
性能的考慮
Flume性能相對比較低,主要有以下幾點:
① 單線程。
Flume 每個 Agent 分為 source,channel,sink 等插件。每個插件都只啟用單線程處理。如果任務是寫數據庫等 IO 操作,性能必然會被拖累。
②source的Timer機制
Source 線程在檢測有新的更新,會一直讀取推向 Channel,當所有的更新處理完畢,線程會退出。啟動一個 Timer 線程。定期3秒重新啟動,如此反復。在這個過程中,沒有充分利用 Java 的多線程通知機制,每次啟動都有一些調度,排隊,檢測及任務初始化過程。影響性能。
③Flume事務機制
Flume 本身已對事各進行了優化,允許批量提交事件。但本質上還是需要檢測Sink的處理結果,再進行 Commit 或 Roolback。
管理的考慮
如果將一個 agent 的任務處理串,source->channel->sink 理解為一個任務(這個任務是個抽象的概念,Flume 里并沒有這個概念),那么 Flume 從業務腳度上看,就是單任務收集系統。如果需要同時處理兩個任務,必須開啟兩個 Flume Agent 進程。隨著收集任務的增加,必然會大大增加管理成本。
(flume處理:多進程處理多任務)
(Bloodhound處理:單進程處理多任務)
此外,我們還有監控需求,統計需求,任務管理等。這些任務需要和我們的 grafana 平臺打通。綜合考慮下,我們選擇自研日志收集系統。
BloodHound系統
項目名稱來源
From wikipedia:
The Bloodhound is a large scent hound, originally bred for hunting deer, wild boar, and since the Middle Ages for tracking people. Believed to be descended from hounds once kept at the Abbey of Saint-Hubert, Belgium, it is known to French speakers as the Chien de Saint-Hubert.
This breed is famed for its ability to discern human scent over great distances, even days later. Its extraordinarily keen sense of smell is combined with a strong and tenacious tracking instinct, producing the ideal scent hound, and it is used by police and law enforcement all over the world to track escaped prisoners, missing people, lost children and lost pets.
“嗅覺最靈敏的獵犬,寓意是能從包括流量在內的各種粗糙的原始數據中提煉中初步有價值的信息。”
項目需求
多任務管理系統
強擴展性
任務監控
高性能
項目架構
系統分層
核心框架層
為了充分利用Flume的功能特性,我們也將Bloodhound拆分層source->channel->sink三個層次。這個設計是為了充分利用Flume中的豐富插件資源,請參照以下配置文件。
時序圖
source 層
source為數據輸入,通常為文件,消息系統等。示例中的Source為Redis,Source為單獨運行的線程,從Redis中指定的隊列中獲取輸入,讀取完成后則推向 Channel。當 Channel 中隊列已滿時,則 source 線程則進入等待。
Channel 層
Channel 作為樞鈕,連接 Source 和 Channel,主要功能如下:
維護一個隊列,接受 source 的 put,向 Sink 發送處理。
管理一個線程池,調度 Sink 任務。由于 Sink 通常較慢,因此整個核心模塊中,只有 Sink 為多線程處理,其余均為單線程執行。
控制QPS,可以使用令牌或漏斗,主要目的是保護高并發寫入的環境下,Sink 對應的數據庫或 Redis。不至于壓力過大,影響正常業務請求。
發送 Metrics,提供實時監控數據來源。
Channel 層主要的方法有:popEvents, addEvents, notifyEvents, sendMetrics等。
Sink 層
Sink 層為一個 Runnable,接受 Events,被 Channel 調度,執行最終的落地邏輯。
以上三層中,Channel 層有 MemoryChannel 和 FileChannel,如果任務比較重要,應該選擇 FileChannel,可以保證進程中斷后,Event 不會被丟失。MemoryChannel 管理一個 Queue,性能相對比較高。Source 和 Sink 可以大量復用Flume中的插件代碼。
任務管理器
任務管理器,故名思義是管理整個日志收集系統的管理模塊。
1 任務管理
任務注冊接口:可通過任務注冊接口向整個進程提交一個任務,如配置所示,任務注冊接口是通過一個 http post 方法提供注冊并啟動一個新的任務。
數據提交接口:默認情況下,Source 是 pull 模式,從文件中,隊列中拉取日志。同時也支持 http 方式提交。數據提交接口需要傳遞兩個參數,jobName 和 events 。
2 任務監控
查看任務執行情況:在grafana中查看各個任務執行情況,這個數據由核心框架層提供。
查看任務運行情況:提供列表,查看任務狀態,啟動,停止任務。
系統運維層
進程管理:使用supervisor管理進程。
調度器:根據各個業務情況,使用調度任務對任務進行管理。調用任務管理中的任務啟動,停止等。這一塊和日志收集核心不太相關,就不再贅述。
結語
筆者從事過多個項目需要使用日志收集,同時也使用了 logstash, flume 等開源系統,總體感覺開源系統比較成熟,有大量插件,事務管理。但和自已業務系統結合不夠緊密。自研框架工作量較大,也會有很多坑,優勢是較好的和業務接軌。
來自:http://www.freebuf.com/sectool/168471.html