Better ELK, 新浪實時日志分析服務進化
【編者的話】我從2014年初入職新浪后就開始接觸實時日志分析相關的技術,主要是ELK(Elasticsearch, Logstash, Kibana),當時是學習+ELK優化,接一些日志,小打小鬧。從2015年起,我們正式得把實時日志分析分析作為服務提供給公司的其他部門。今天要給 大家分享的是在服務化的道路上,我們的想法,方案和疑問。
---
服務介紹
隨著實時分析技術的發展及成本的降低,用戶已經不僅僅滿足于離線分析。目前我們服務的用戶包括微博,微盤,云存儲,彈性計算平臺等十多個部門的多個產品的日志搜索分析業務,每天處理約32億條(2TB)日志。
技術架構
簡單介紹一下服務的技術架構:
這是一個再常見不過的架構了:
(1)Kafka:接收用戶日志的消息隊列
(2)Logstash:做日志解析,統一成json輸出給Elasticsearch
(3)Elasticsearch:實時日志分析服務的核心技術,一個schemaless,實時的數據存儲服務,通過index組織數據,兼具強大的搜索和統計功能。
(4)Kibana:基于Elasticsearch的數據可視化組件,超強的數據可視化能力是眾多公司選擇ELK stack的重要原因。
努力提供更好的服務
我這次分享的重點不是這種架構的優劣或為什么選擇這樣的架構,而是在如此的架構上如何更好地傳遞實時日志分析的價值。為用戶做好服務也不是修改幾個配置文件,調優幾個程序運行參數就能搞定的。為了提供更好的服務,我們在下面三個方向做了努力:
一、提升服務質量
我們首先做了Elasticsearch優化,Hardware Level由于我們當時拿到機器沒有選擇余地,只開啟了超線程;System Level的優化如關閉swap,調整max open files等;App Level的優化如Java運行環境版本的選擇,ES_HEAP_SIZE的設置,修改bulk index的queue size等,另外還設置了默認的index template, 目的是更改默認的shard,replica數并將string改為not_analyzed, 開啟doc_values,以應對elasticsearch進程OOM。詳細的優化內容見 Elasticsearch Optimization Checklist 。
隨著用戶數據的不斷增長,index管理也成了大問題,我們需要基于大量不同的用戶配置定期的create, optimize, close, delete, snapshot不同的index,在某個服務器上手工配置crontab已是不可能,而且cron是單點。于是我們開發了一個獨立的 Elasticsearch Index管理系統,負責以上任務的調度及執行。這個管理系統背后使用的技術是Celery,一個用Python開發的任務隊列及執行系統,提供了類似 crontab的定時任務配置語法,并且實現了分布式,可用性更高的架構。
最近的服務升級,我們為Elasticsearch安裝了Hdfs Snapshot插件,可以定期將index 備份到Hdfs,這個功能目前主要用于備份Kibana的配置index,用以恢復用戶查看或配置可視化界面時的錯誤操作。
監控報警方面,System Level的監控報警(如硬盤滿,損壞,服務器宕機)直接使用了在新浪內部提供了多年服務的sinawatch;App Level(如Elasticsearch JVM Heap Usage過高,Kibana能否正常訪問,Kafka topic的consumer offset lag), 我們開發了對應的監控報警腳本。User Level(如日志解析失敗數量),主要通過elasticsearch python client執行 query
去統計或搜索。常見的報警是Logstash-filter-grok,logstash-filter-json解析日志失敗會輸出的json中添加_grokparserfailure,_jsonparsefailure,我們執行query判斷解析錯誤的量。
要說明的是,Marvel是Elasticsearch很好的監控工具和插件,但是它們是商業軟件,我們沒有采用。Marvel是基于Kibana做的,里面對一些重要指標(如index bulk reject number)的展示很有價值。
二、增強易用性
增強服務的易用性就是給用戶更好的用戶體驗,減少用戶的抱怨。ELK性能優化是一方面,但它是遠遠不夠的,我們遇到的實際情況是,用戶在其他方面抱怨更多,如下:
(1)用戶最先抱怨的是IP解析成地區、ISP信息一點都不準,完全沒有參考意義
如對于CDN這種服務,我們解析用戶IP不準,定位問題邊緣節點錯誤,問題沒法查,這是幫倒忙。原因:Logstash默認自帶的IP庫是國外 maxmind公司的免費版本,中國的信息尤其不準。解決方案:使用我浪較新較全的IP庫生成能適配maxmind geoip2 api的二進制格式IP庫(maxmindDB),再開發logstash-filter-geoip2來解析IP。實測不僅IP解析準確率與公司IP庫 相同了,解析速度也提高了。
(2)然后我們與用戶都發現日志接入流程復雜,溝通困難。
人做不到機器那樣分毫不差,有啥說啥。接入用戶日志的時候,例如常常因為用戶對日志格式表達的不全面,模棱兩可,導致日志解析失敗,服務對接人多 次重寫配置。從用戶提需求到用戶可以看到數據可視化效果或搜到日志,需要幾個小時到幾天。一來二去,用戶和我們都煩了,只能求變。為此,我們正在逐步實現 用戶數據接入的自動化,減少接入時間和溝通成本這個過程需要3個關鍵:A.用戶配置日志格式的界面,盡可能簡潔簡單;B.根據用戶配置自動生成 logstash config, index管理需要的配置;C.自動部署配置(logstash config等),打通日志流。
后來我們做了一個簡單的用來協商日志格式的界面:
目前我們已完成了A的一部分:用戶日志格式配置界面;B的全部:開發了自動生成logstash conf的 python api;C即將開始,并且考慮使用docker技術為我們提供一些便利。
(3)部分數據可視化需求得不到滿足,Kibana配置難度大
我們起初采用官方Kibana v3, 用戶提出的類似SQL中的多個group by,畫百分比,求指定區間占比等常見需求無法滿足。之后通過三斗大神(微博@argv)定制版的 Kibana 3 滿足了一些用戶需求。Kibana 4誕生后,代碼幾乎是對Kibana3的重寫,做了大幅改進,通過 Elasticsearch Aggregation
的強大數據統計功能及靈活的配置從Kibana 3解放出來。近期我們將遷移到Kibana 4。
三、提供新功能
我們為Elasticsearch安裝了國內medcl大神開發的ik中文分詞插件 elasticsearch-analysis-ik 。之前被分詞為”中“和”國“的中國,現在終于可以被當做一個完整的詞匯,否則搜索”中國“,“美國”也會出現。微盤的一些離線搜索需求使用了我們的服務,也用到了中文分詞,Elasticsearch的搜索天賦滿足了他們的需求,減少了他們的痛苦。
我們經歷過的坑和坎兒:
(1)elasticsearch 進程JVM Heap High Usage( >90% )
很長一段時間,我們都在應對JVM Heap High Usage,他帶了的問題是Old GC次數多,時間長,es節點頻繁退出集群,整個集群幾乎停止響應。現在我們的主要策略是開啟doc_values;限制query執行時占用的JVM Heap size;analyzed string只允許做query, 不允許facets或者aggs;定期close 用戶不需要的index。
(2) Elasticsearch Query DSL, Facets, Aggs學習困惑
有人為此開發了使用SQL執行ES Query的插件,一定程度上減輕了進入門檻。我們給出的學習他們的建議是觀察Kibana的Request Body或試用Marvel的Senese插件,它有自動完成Query,Facets, Aggs的功能。另外最常用的query是 query string query
,最常用的aggs是 Terms
, Date Histogram
,可以應付大部分需求。
(3)logstash不工作
非官方的問題插件,及使用logstash-filter-ruby時未考慮到的異常等,導致Logstash運行時工作線程(worker thread)異常退出,Logstash僵死。我們的建議是盡可能不要在config中使用logstash-filter-ruby,盡量使用官方插 件。不過我們也遇到過復雜的日志,寫過250行+的config,用盡了ruby filter。當前未發現Logstash有好的成熟的監控方案,Logstash的內部狀態也獲取不到。我們目前通過間接的監控Kafka topic consumer是否落后或elasticsearch indexing rate來檢驗logstash的工作情況。
(4)Kibana沒有用戶的概念,不同用戶的數據無法隔離
多個用戶共享的Kibana Dashboard, 誤操作或誤刪時常影響其他用戶,保存的dashboard太多,找到特定的dashboard很困難。官方到目前為止,未在這方面做過改進。有很多非官方 的改進,我們也曾經用過三斗大神定制的Kibana3,也對Kibana index做了snapshot儲存到Hdfs里面。
(5)與用戶溝通成本高
與我們的用戶協商日志格式,數據可視化配置時,由于人的不確定性容易造成多次來回確定和修改,效率低下。我們畢竟是提供日志分析服務的,不給用戶 做日志運維,所以近期也在探索通過日志接入自動化、推薦用戶提供給我們json格式數據,定期組織用戶的Kibana培訓來減少溝通成本。
---
Q & A:
問:logstash連es出現timeout的情況有沒?如何解決的?
答:我們常見的是ES Jvm Heap Usage比較高的時候會timeout,如果是服務內存小換大內存。另外不要對analyzed的string做aggs,facets ,開啟doc_values。
問:關于日志中異常報警的,有哪些方式?關鍵字過濾?
答:對于日志解析失敗的情況,logstash 常見的是_grokparsefailuer,和_jsonparsefailure,數據寫入es后,執行query查詢這兩個關鍵詞的數量即可。對于 報警方案,watch是官方剛出的,其實比它早的實現方案,如Yelp的elastalert。
問:大數據分析平臺(基于hdfs)跟kibana的展現會有很大區別嗎?或者說最大的區別會在哪些方面?
答:你說的區別,我理解是hadoop與elasticsearch的區別,一個是離線分析,以job為單位,一個是實時搜索和統計,以 query為單位。這里有三個關鍵詞:實時,搜索,統計。hadoop是離線的,es是實時的;es本質上是一個搜引擎,可以用來做全文檢索等工 作,hadoop顯然于此無關。統計是hadoop與es都能做的,我不了解hadoop有沒有像Kibana這樣的數據可視化組件。
問:你們的ES集群數據節點和查詢節點做了分離嗎?logstash是直接把數據寫入查詢節點還是數據節點?另外你們直接用的node模式還是transport模式呢?
答:(1)還沒有做分離。(2)我們還在用http protocol模式