在我們的服務器上通常會生成各種日志文件,比如系統日志、 應用日志、安全日志。當系統發生故障時,工程師需要登錄到服務器上,在日志里查找故障原因。
如果定位到處理請求的服務器部署了多個實例,那么就需要到每個實例的日志目錄下去查看日志。另外每個服務器實例還需要設置日志滾動策略,比如每天生成一個文件,以及日志壓縮歸檔策略等。
管理分布式集群的多臺服務器的日志,是很麻煩的事情。尤其是排查故障的時候,服務器太多通過日志找故障太麻煩。因此需要把這些服務器的日志集中管理,并提供集中檢索功能,這樣就可以提高故障診斷的效率。
業界通用的日志數據管理方案主要包括 Elasticsearch 、 Logstash 和 Kibana 三個組件,這三個組件又先后被收購于Elastic.co公司名下。取三個組件的首字母,業界把這套方案簡稱為ELK。
什么是ELK?
Logstash :數據收集處理引擎。支持動態的從各種數據源搜集數據,并對數據進行過濾、分析、豐富、統一格式等操作,然后存儲以供后續使用。
Elasticsearch :分布式搜索引擎。具有高可伸縮、高可靠、易管理等特點,可以用于全文檢索、結構化檢索和分析。ES 基于 Lucene 開發,Lucene是現在使用最廣的開源搜索引擎之一,Wikipedia 、StackOverflow、Github 等都基于Lucene來構建搜索引擎。
Kibana :可視化平臺。能夠搜索、展示存儲在 Elasticsearch 中的索引數據,使用Kibana可以很方便地用圖表、表格、地圖展示和分析數據。
Logstash部署架構
常見的Logstash的部署架構如下圖所示,主要由Shipper、Broker和Indexer三個角色組成。

- Shipper:日志收集者,也就是Agent。負責監控本地日志文件的變化,及時讀取日志文件的最新內容,經過處理輸出到Broker。
- Broker:日志Hub,用來連接多個Shipper和多個Indexer。redis是Logstash官方推薦的Broker,支持訂閱發布和隊列兩種數據傳輸模式。
- Indexer:日志存儲者。負責從Redis接收日志,經過處理,比如對文本進行格式化,之后寫入到本地文件。
無論是Shipper還是Indexer,Logstash始終只做三件事:日志的收集、過濾和輸出。主要由三個部分組成:Input 、Filter、Output。

Logstash實例由Input、Filter、Output組成
Input(輸入):Logstash實例通過Input插件可以讀取多種數據源,輸入數據可以是JAVA日志、Nginx日志 、TCP連接、控制臺輸入 、Syslog(系統日志)、Redis 、Collectd(系統監控守護進程)等。
Filter(過濾):通過Filter插件可以將日志轉換為我們需要的格式。Logstash 提供了豐富的Filter插件,包括date(日志解析)、grok(正則解析)、dissect(分隔符解析)、mutate(字段處理)、json解析、geoip(地理位置數據解析)、ruby等。
Output(輸出):通過 Output 插件可以實現數據的多份復制輸出,輸出目標可以是控制臺、Redis 、TCP 、文件、Email等,目前業內常用的輸出方式是和搜索引擎Elasticsearch來對接。
接下來我們看一下Logstash與ES如何配合實現ELK架構。
ELK架構

ELK架構
數據收集端:每臺服務器都在上面部署 Logstash Shipper來收集日志,經過處理傳輸到 Elasticsearch 集群。
數據存儲與搜索:采用多個 Elasticsearch 節點組成 Elasticsearch 集群,采用集群模式運行,可以避免單個實例壓力過重的問題。
數據展示:Kibana 可以根據 Elasticsearch 的數據來繪制各種各樣的圖表,直觀的展示業務實時狀況。

Kibana
加入隊列的ELK
當并發量較大的時候,由于日志傳輸峰值較高,會導致 Elasticsearch 集群丟失數據。對于這種Logstash數據超過ES集群處理能力的情況,可以通過隊列就能起到削峰填谷的作用, Elasticsearch 集群就不存在丟失數據的問題。
目前業界在日志服務場景中,使用比較多的兩種消息隊列是Kafka和Redis。Redis 隊列多用于實時性較高的消息推送,并不保證可靠。Kafka保證可靠但有點延時。

Kafka作為隊列加入ELK架構
輕量級的Agent方案:Filebeat
Filebeat 是基于原先 logstash-forwarder 的源碼改造出來的,用 Golang 編寫,無需依賴 Java 環境就能運行,安裝包10M不到。
Filebeat效率高,占用內存和 CPU 比較少,可以解決在服務器上部署Logstash shipper消耗資源較高的問題,非常適合作為日志收集系統的Agent運行在服務器上。

ELK/EFK總結
基于 ELK或EFK的分布式日志解決方案的優勢主要體現在以下幾個方面:
- 擴展性強:采用高可擴展性的分布式系統架構設計,可以支持每日 TB 級別的新增數據。
- 使用簡單:通過用戶圖形界面實現各種統計分析功能,簡單易用,上手快
- 響應迅速:從日志產生到查詢可見,能達到秒級完成數據的采集、處理和搜索統計。
- 界面美觀:Kibana 界面上,只需要點擊鼠標,就可以完成搜索、聚合功能,生成炫麗的儀表板。
對于除了ELK方案以外,在分布式日志管理上,我們還有很多其他的選擇。近年來隨著大數據的發展,海量數據采集組件Flume也開始廣泛應用于分布式日志解決方案中。因為沒有太多日志分析需求,我的團隊采用了更輕量級的方案:Loki + promtail + grafana,建立類似Prometheus的日志監控系統,promtail負責收集日志,Loki負責存儲,grafana負責展示。