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

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

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

ELK架構(gòu)
數(shù)據(jù)收集端:每臺(tái)服務(wù)器都在上面部署 Logstash Shipper來收集日志,經(jīng)過處理傳輸?shù)?Elasticsearch 集群。
數(shù)據(jù)存儲(chǔ)與搜索:采用多個(gè) Elasticsearch 節(jié)點(diǎn)組成 Elasticsearch 集群,采用集群模式運(yùn)行,可以避免單個(gè)實(shí)例壓力過重的問題。
數(shù)據(jù)展示:Kibana 可以根據(jù) Elasticsearch 的數(shù)據(jù)來繪制各種各樣的圖表,直觀的展示業(yè)務(wù)實(shí)時(shí)狀況。

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

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

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