分布式技術(shù)原理與實戰(zhàn)45講--第45講:分布式下如何實現(xiàn)統(tǒng)一日志系統(tǒng)
在業(yè)務(wù)系統(tǒng)開發(fā)中,日志的收集和分析很重要,特別是在進行故障分析時,日志記錄得好,可以幫我們快速定位問題原因。在互聯(lián)網(wǎng)分布式系統(tǒng)下,日志變得越來越分散,數(shù)據(jù)規(guī)模也越來越大,如何更好地收集和分析日志,就變成了一個特別重要的問題。
傳統(tǒng)的日志查看
查看日志對工程師來說最簡單不過了,雖然有了各類日志分析工具,但還是要熟悉命令行語句的操作,特別是在很多大型公司的面試中,都會考察求職者對 Linux 基本指令的應用和熟悉程度。下面我們一起來回顧一下。
Linux 查看日志的命令有多種:tail、cat、head、more 等,這里介紹幾種常用的方法。
tail 和 head 命令
tail 是我最常用的一種查看方式,典型的應用是查看日志尾部最后幾行的日志,一般會結(jié)合 grep 進行搜索應用:
tail -n 10 test.log
tail -fn 1000 test.log | grep 'test'
head 和 tail 相反,是查看日志文件的前幾行日志,其他應用和 tail 類似:
head -n 10 test.log
more 和 less
more 命令可以按照分頁的方式現(xiàn)實日志內(nèi)容,并且可以進行快速地翻頁操作,除了 more 命令以外,常用的還有 less 命令,和 more 的應用類似。
cat
cat 命令用于查看全部文件,是由第一行到最后一行連續(xù)顯示在屏幕上,一次顯示整個文件,一般也會結(jié)合 grep 等管道進行搜索。
除了基本的指令以外,還有 AWK 和 SED 命令,用于比較復雜的日志分析,例如,sed 命令可以指定對日志文件的一部分進行查找,根據(jù)時間范圍,或者根據(jù)行號等搜索。關(guān)于 AWK 和 SED 詳細的應用說明,你可以結(jié)合 help 指令查看命令示例。不過呢,我的建議是只要了解基本操作就可以,一些比較復雜的語法可以通過查看手冊或者搜索類似的命令行應用來實現(xiàn):
The GNU Awk User’s Guide
sed, a stream editor
為什么需要統(tǒng)一日志系統(tǒng)
使用上面的 Linux 指令進行日志查看與分析,在單機單節(jié)點下是可以應用的,但是如果擴展到分布式環(huán)境下,當你需要查看幾十上百臺機器的日志時,需要不停地切換機器進行查看,就會變得力不從心了。
你可以思考一下,在分布式場景下,除了不方便查看集群日志以外,傳統(tǒng)日志收集都存在哪些問題?
無法實現(xiàn)日志的快速搜索
傳統(tǒng)的查找是基于文件的,搜索效率比較低,并且很難對日志文件之間的關(guān)系進行聚合,無法從全局上梳理日志,也很難進行調(diào)用鏈路的分析。
日志的集中收集和存儲困難
當有上千個節(jié)點的時候,日志是分布在許多機器上的,如果要獲取這些日志的文件,不可能一臺一臺地去查看,所以這就是很明顯的一個問題。
日志分析聚合及可視化
由于日志文件分布在不同的服務(wù)器上,因此進行相關(guān)的分析和聚合非常困難,也不利于展開整體的數(shù)據(jù)分析工作。
除了這些,還有日志安全問題,以電商場景為例,很多業(yè)務(wù)日志都是敏感數(shù)據(jù),比如用戶下單數(shù)據(jù)、賬戶信息等,如何管理這些數(shù)據(jù)的安全性,也是一個很關(guān)鍵的問題。
ELK 統(tǒng)一日志系統(tǒng)
我在之前的工作中,曾經(jīng)負責搭建了業(yè)務(wù)系統(tǒng)的 ELK 日志系統(tǒng),在 第 25 課時 我們介紹 ElasticSearch 技術(shù)棧時中曾經(jīng)提到過 ELK Stack,就是下面要說的 ELK(ElasticSearch Logstash Kibana)日志收集系統(tǒng)。
ElasticSearch 內(nèi)核使用 Lucene 實現(xiàn),實現(xiàn)了一套用于搜索的 API,可以實現(xiàn)各種定制化的檢索功能,和大多數(shù)搜索系統(tǒng)一樣,ElasticSearch 使用了倒排索引實現(xiàn),我們在第 25 課時中有過介紹,你可以溫習一下。
Logstash 同樣是 ElasticSearch 公司的產(chǎn)品,用來做數(shù)據(jù)源的收集,是 ELK 中日志收集的組件。

Logstash 的數(shù)據(jù)流圖如上圖所示,你可以把 Logstash 想象成一個通用的輸入和輸出接口,定義了多種輸入和輸出源,可以把日志收集到多種文件存儲中,輸出源除了 ElasticSearch,還可以是 MySQL、Redis、Kakfa、HDFS、Lucene 等。
Kibana 其實就是一個在 ElasticSearch 之上封裝了一個可視化的界面,但是 Kibana 實現(xiàn)的不只是可視化的查詢,還針對實際業(yè)務(wù)場景,提供了多種數(shù)據(jù)分析功能,支持各種日志數(shù)據(jù)聚合的操作。
ELK 系統(tǒng)進行日志收集的過程可以分為三個環(huán)節(jié),如下圖所示:

使用 Logstash 日志收集,導入 ElasticSearch
Logstash 的應用非常簡單,核心配置就是一個包含 input{}、filter{}、output{} 的文件,分別用來配置輸入源、過濾規(guī)則和配置輸出。下面的配置是一個典型的實例:
在 ElasticSearch 中實現(xiàn)索引處理
日志數(shù)據(jù)導入到 ElasticSearch 中以后,實現(xiàn)索引,在這一步中,可以針對不同日志的索引字段進行定制。
通過 Kibana 進行可視化操作、查詢等
作為一個商業(yè)化產(chǎn)品,Kibana 已經(jīng)支持了非常豐富的日志分析功能,并且可以選擇應用一些機器學習的插件,可以在 Kibana 的官方文檔 中了解更多。
在我之前的系統(tǒng)設(shè)計中,是使用 Flume 進行容器內(nèi)的日志收集,并且將日志消息通過 Kakfa 傳送給 Logstash,最后在 Kibana 中展示。這里分享我之前的一篇關(guān)于 ELK 的技術(shù)文章,作為補充閱讀: ELK 統(tǒng)一日志系統(tǒng)的應用。
總結(jié)
今天分享了業(yè)務(wù)開發(fā)中關(guān)于日志收集的一些知識,包括常用的日志分析命令、傳統(tǒng)日志收集方式在分布式系統(tǒng)下的問題,以及應用 ELK 技術(shù)棧進行日志收集的流程。
日志作為系統(tǒng)穩(wěn)定性的重要抓手,除了今天介紹的日志分析和統(tǒng)一日志系統(tǒng),在業(yè)務(wù)開發(fā)中進行日志收集時,還有很多細節(jié)需要注意。比如 Java 開發(fā)中,在使用 Log4j 等框架在高并發(fā)的場景下寫日志可能會出現(xiàn)的日志丟失,以及線程阻塞問題,還有日志產(chǎn)生過快,導致的磁盤空間不足報警處理等。
你在開發(fā)中有哪些日志收集和應用的心得體會,歡迎留言進行分享。
如果你覺得課程不錯,從中有所收獲的話,不要忘了推薦給身邊的朋友哦。前路漫漫,一起加油~