日志漫談:不同規模下的日志運維與優化
【51CTO.com原創稿件】企業規模不同,日志運維的方式就有所不同。在WOT2016移動互聯網技術峰會上,來自新浪微博的資深系統開發工程師于炳哲,同與會者深入分析了小企業與大企業的日志運維問題,手機微博日志系統架構相關的調優,以及自己對日志運維的反思。
小企業日志運維
小企業日志運維關注點在于:成本、數據規模以及維護的難度。首先,我們來看看小企業在不同規模下的日志架構。小企業日志架構的特點:擴展相對簡單、業務復雜度低、業務依賴度低、歷史遺留問題相對較少,所以重構成本相對較低、可投入的資源相對較少。
其實對于小企業來講可能都會經歷幾個階段,首先是開荒的階段,即是服務剛剛上線,還處于測試和開發的階段。這時候,企業的應用可能就是布置一臺或者兩臺服務器,此時沒有必要做一套完整的日志架構。用純文本 + grep + awk + sed即可完成日志的提取。如果使用傳統的數據庫,可以在開發中將重要數據直接寫入數據庫。或者使用第三方監控,采用業務接口監控(lua -> nginx shard dict -> DB(graphite))。
然后,進入數據增長階段。此時的架構變成了分布式,也就是日志可能在不同的服務器上,業務也已經上線,這時候需要及時的反饋信息,需要專業的運維人員做日志架構設計。如下圖的基于ALK簡單的設計:
隨著日志的逐漸增多,業務的逐漸擴展,進入了日志服務器中轉階段,此時需要收集的日志總量還未達到Elasticsearch(單數據節點)的寫入量,企業對日志數據的安全性要求并不是特別高,同時對單點問題也不是很重視。在盡量少的運維投入下,希望快速構建。不要有太高的技術門檻。
這時候架構可能就會變成這樣,這是一個大家中小企業,或者在50人以下,KPI在幾萬左右的廠商,基本就可以采用這種架構。就是說你的前面是日志agent,把日志直接寫到日志服務器上,直接落磁盤。在這個上面用logstash或者其他的一些日志處理的組件,直接進行收集,把日志寫到ES里。在這個階段還沒有到達一個ES的性能瓶頸,我一直強調的是在整個日志的架構當中不需要一下把這個架構架的特別完美,而是要強調這種漸進的方式,因為成本是很重要的,對于小企業來講。
這時提出了一個新的要求,就是前端服務器已無法承載增幅的日志量,日志需要統一歸檔,就此進入隊列階段。這時需要考慮數據安全問題,保障日志安全不丟失。同時需要一寫多讀。所謂一寫多讀就是你的日志架構是往一個地方寫,同時有多個地方進行消費,比如說業務部門,或者是你的運維部門。
現在比較流行的一個日志處理的架構,前端也是agent寫入,同時中間使用kafka或者redis這種緩沖的隊列做相應的隊列存儲。然后通過logstash indexer,把這個數據寫到ES里面,或者寫到DB里面。同時我這里面用了kibana做一些數據展示。在這個里面你要考慮隊列的選型問題,首先隊列選型問題,如果使用redis可能涉及到一個成本的問題,它的內存,如果數據比較多的話,你的內存是比較昂貴的,在成本上面可能要考慮。另外還有一個是分布式的問題,如果你用redis進行分布式方面的話,它本身是不支持這種的,你可能需要一些其他的組件來做這個redis的分布式。其實我比較建議的是使用開包即用的kafka,它可以說是天生的分布式的隊列,它是用磁盤做這種數據存儲的,所以在成本方面也是相對比較低廉的。
在此,我想強調的是存儲的擴展,比如說ES存儲的擴展,這個可能是一個常用的、常規的一個擴展架構,就是一個分角色的架構。最前端用client,前面掛一個LB的方式做負載均衡,然后把數據寫到client上。隨后在client和ES的Node進行交互,同時使用master進行整個集群數據狀況的一些保存。對于一些中小規模的企業,能做到這一步基本就夠用。
最后,對于小企業日志運維,我有以下幾點補充:一是,一切架構設計都要以測試為先,同時做好監控。二是,涉及到logstash和Rsyslog的問題,logstash本身可能涉及到的它的整個日志傳輸,涉及到一些不可控的問題,它雖然是開源的,但是它很多的一些過程并沒有很好的自帶的監控,丟不丟日志,傳輸過程中有沒有問題,實際上你是不知道的,你只能是通過業務兩邊進行對數。三是,Rsyslog提供impstats監控模塊。impstats模塊專門做事件級別的監控,已經精確到某一個事件是成功還是失敗的這種監控,而且性能非常好。通過Rsyslog的rmpc的模塊,我們可以做整個日志傳輸的監控。最后,Elasticsearch的監控可以使用自帶的插件。Elasticsearch的監控我推薦,如果是在人力投入并不是特別強的公司,可以直接完全使用它自帶的一些插件,同時可以使用比如說Elasticsearchmabo這種插件。
大企業日志運維
大企業日志系統的特點和關注點在于:成本、運營與運維數據復雜性、歷史遺留問題較多、各部門相互依賴、應對業務突增情況的能力以及丟失率監控&SLA(針對日志傳輸丟失情況的長久數據,都要保存到SLA里面,在SLA里面做一些你系統的一些評價,就是你這個系統到底靠不靠譜,其實是要用SLA來衡量的。)。
談到大規模的日志傳輸,我們首先要考慮這個架構到底要怎么設計,到底是使用同步架構還是使用異步架構。什么叫同步架構?就是ETL、格式整理和轉發放在一起。這會存在一個什么問題?如果整個業務比較平穩的話還好。但是如果業務突然間出現爆增等突發情況的時候,上面的架構就會出現問題。你需要解析的,可能就放在那個地方,后面的數據又轉發不出去,前的服務發生了什么你可能根本不知道。此時,就需要把傳輸和解析進行分隔。
因此,我建議在設計日志傳輸架構的時候盡量設計成異步架構。
如何控制成本和優化業務呢?日志量越大成本就會越大,日志量大不是可以用來自豪的事情。可以用來自豪的是,你的成本做了多少意義的事情。在大企業的日志傳輸中其實存在很多垃圾數據,沒有收集的意義。所以我們首先要做的就是對日志進行分類。然后就是對格式進行協定,對日志進行合并以及分級傳輸,實現運維侵入開發。
以Rsyslog為例,首先所有日志要有志tag,以其進行區分。然后需要高保的tag調用高保RuleSet,其他的日志tag以syslogfacility-text進行區分,通過syslogfacility-text來寫入普通的通道。最后使用rsyslog的action中的屬性:action.execOnlyEveryNthTime實現按比例丟棄。
接下來,我重點介紹一下日志降級。日志降級是用來干什么的?在企業的業務量遇到突發情況的時候,需要對服務進行降級。為什么要降級?因為正常情況下,日志量處于一個比較平穩的狀態,一點點的傳。類似于某某明星離婚的時候,這個日志量就會爆增。為什么會爆增呢?首先日志是有一個特點的,在正常情況下可能就記錄一下infor或者這些日志,但是如果出現錯誤的時候,這個錯誤量就會跟著這個業務量一樣樣的往上漲。這時就要考慮日志降級的問題,如果不降級的話,很有可能把下行帶寬全部打滿,遭遇計算量、帶寬以及磁盤三個瓶頸。
以手機微博為例,我們來看看日志降級的邏輯。首先,就是要動態調整各個日志tag的級別。然后,它定義了兩種級別:是否轉發與是否落磁盤。
這是一個邏輯的圖,這里面我們用了一個PHP的動態加載庫,它可以把你相應的降級規則,就是對某一個日志,在需要降級的時候把它降到哪個通道里,把它降到哪個級別里的定義。然后我們會和監控進行連接,當監控發現某些業務突然出現突增的時候。這里面當然是基于規則,如果說這個規則滿足的時候,就開始進行降級。
在大企業日志運維的情況下,我們需要注意,企業的日志傳輸是需要監控的,對于架構的每個環節都需要進行測試,主要是壓測。此外,最好通過隊列解藕各個部門的依賴,并實現運維侵入開發,及時發現問題反饋給開發,發現開發中的不合乎規范的問題,并提供解決方案。
微博日志系統架構及相關調優
調優從來就沒有一個標準的答案,所有調優一定要從內部了解系統開始,調優一定要基于測試與監控。下面,我們以Elasticsearch和Rsyslog的調優為例來具體了解一下:
◆Elasticsearch的調優
我們經常強調Elasticsearch的調優到底在調什么,我們首先要看一下一條數據寫進來的時候是經過怎樣的過程。首先是把數據寫到index-buffer當中,在這個階段你的數據還是搜索不到的。然后會有異步的程序把這個數據從index-buffer當中refresh出來,這個就是refresh階段。一講到Elasticsearch調優的時候,肯定大家就要講到有一個調優項叫做index-buffer refresh,這個refresh的間隔時間。然后就到了這個flosystem cache這一層,到了這一層的時候你的數據是可以被搜到了,因為它可能就進行切分。最后一步是磁盤操作flush,把數據從flosystem-cache刷到磁盤當中。進入disk層有個merge階段,也就是說其實在ES當中是有一個異步的進程,Merge這個數據,就是把system進行合并,這個操作因為它是IO操作,它對性能的損耗是比較大的。再就是translog,它實際是一個數據庫記錄操作日志,把所有的對ES的操作首先先記到translog當中,如果在系統寫入發生異常的時候,從translog把操作進行恢復。在flush寫入之后,刪除translog。
至此,我們可以看到,在寫入的過程中,ES的性能主要merge、flush、reflush,還有translog的flush的階段被消耗。了解到這個過程,我們就可以參照ES的官方文檔,去對相應的各個階段進行調優。當然首先要知道企業的性能狀態,如果IO有問題就調merge,如果CPU的問題可以考慮在reflush方面做調整。
然后就是調優的方向,merge官方默認參數是按照SSD的磁盤來做的調優,實際它是不太適合機械磁盤這種服務的。因此,我建議如果涉及到IO問題,可以考慮把merge的進程數調低。在數據寫入特別大時,采取網絡限流。在內核層面,ES配置文件里含有了一些系統提供的很好的參數。
◆Rsyslog的調優
如圖所示,這是Rsyslog一個內部隊列,Rsyslog的內部也是比較復雜的。首先是input的這個進程,接著是預處理的階段,比如它會進行一些分類,把你的某一個日志tag按照一個什么分類寫到一個什么地方。再往后就是filter Engine,在這之前會有一個Queue,就是說這個數據在內部會維護一個隊列,然后Filter到這個隊列里主動拉取數據。后面是Action processor,它在前面也有每一個事件的隊列,Action的進程會從相應的隊列當中寫數據。這就是的內部的結構。
Rsyslog主要有Main queue和Action queue兩種類型的隊列,四種隊列設置,分別是:Direct queue、Disk queue、In-memory queue(LinkedList、FixdArray)、Disk-assisted memory queue。
總結
日志量就是成本,所以不要以花了多少錢而自豪,而是要以做了多少事作為目標。要傳輸有價值的數據!要多注意業務優化。此外,一定要記住:選擇哪一種架構由具體的場景決定,不要過度設計,但要盡量快速迭代。
來自:http://network.51cto.com/art/201610/520295.htm