java 版本 Logstash

一.提升性能:

先說說性能問題,當時袋鼠雲的雲日誌系統日誌接收端是ruby 版本的logstash,存儲用elasticsearch,前端的展示沒有用原生的kibana,而是自己寫的一套前端。本人是負者日誌接收端的logstash開發,基於ruby版本的logstash寫一些滿足公司業務的插件,當時為了提升性能做了各種優化,一些模塊也用java寫的,在用ruby調用java,比如ip的解析,但是最終優化的結果是單機4core,4g的虛擬機每小時最多跑800萬的數據(我們的場景跟大部分人一樣都是訂閱kafka的消息,在經過一些filter(瓶頸主要在這裡比較耗cpu),在寫入elasticsearch)。因為logstash的核心代碼是用ruby語言開發,雖然是運行在jruby上,但是由於中間涉及到數據結構的轉化,性能是跟用原生的java語言運行在jvm上肯定是有所差距的。所以當時也是抱著試試的心態,花了2個星期用java重寫logstash,並把自己所需要的插件也用java重寫,在同樣的4core,4g的虛擬機環境下,每小時能跑4000萬數據,性能近5倍的提升。

這是一個java logstash 和 ruby logstash(2.3.2版本)做的性能對比


java 版本 Logstash


二.是保證數據儘量不丟失:

ruby 版本的logstash 對保證數據不丟失這塊沒做太多的設計,舉個簡單的列子,數據從kafka消費,在output到elasticsearch,一旦elasticsearch集群不可能,ruby logstash會重試幾次還不成功就會扔掉繼續消費kafka數據,而且重試的動作也是elasticsearch插件自身完成,logstash本生沒對數據的不丟失做設計。而java 版本的logstash 的BaseOutput 這個抽象類裡面有個failedMsgQueue 這個隊列,每個output實例維護一個,output 插件需要自身判斷哪些數據失敗了,在把失敗的數據調用addFailedMsg 這個方法,寫入到failedMsgQueue這個隊列裡,java logstash一旦發現failedMsgQueue有數據就會調用sendFailedMsg這個方法消費failedMsgQueue這裡的數據直到沒有數據,才會消費input裡的數據這個邏輯可以通過consistency 這個屬性控制,默認是關閉的。還有一點是input和output插件都提供了release方法,這個主要是為了jvm退出時,要執行的一些動作而設計的,因為大部分的input和output插件在獲取和發送的數據都會先放在一個集合裡面,在會慢慢消耗集合裡面的數據,這樣jvm退出時,插件各自就可以實現自己的邏輯保證jvm退出時,集合裡面的數據要消費完,才能退出jvm,當然 你要是kill -9 進程那就沒法保證了。現在elasticsearch插件我們已經實現了數據不丟失這個邏輯,也在我們的線上穩定的跑了很長一段時間。

三 .性能指標數據採集

實時數據的採集最重要的是整個鏈路數據的性能監控,jlogstash統一把讀取數據,過濾數據,寫入數據的性能指標寫入到promethus,可以為後續的性能問題的排查提供支持。

註釋:有人問jlogstash跟hangout有什麼區別,這裡就不做說明了,有興趣的同學可以看看這兩個的源碼就知道區別了。也希望jlogstash能為一些開發者解決一些問題,也希望有更多的人參與到jlogstash的開發裡來。


分享到:


相關文章: