Kafka與ELK實現一個日誌系統

哥不是小蘿莉發表於2022-02-28

1.概述

客戶端應用程式在執行過程中可能會產生錯誤,例如呼叫服務端介面超時、客戶端處理業務邏輯發生異常、應用程式突然閃退等。這些異常資訊都是會產生日誌記錄的,並通過上報到指定的日誌伺服器進行壓縮儲存。 本篇部落格以一個應用實時日誌分析平臺作為案例來講述ELK(ElasticSearch、LogStash、Kibana)在實際業務中的具體用法,讓讀者能夠從中理解ELK適用的業務場景及實現細節。

2.內容

在傳統的應用場景中,對於這些上報的異常日誌資訊。通常適用Linux命令去分析定位問題,如果日誌資料量小,也許不會覺得有什麼不適。假若面對的是海量的異常日誌資訊,這時還用Linux命令去逐一檢視、定位,這將是災難性的。需要花費大量的時間、精力去查閱這些異常日誌,而且效率也不高。 因此,構建一個應用實時日誌分析平臺就顯得很有必要。通過對這些異常日誌進行集中管理(包括採集、儲存、展示),使用者可以在這樣一個平臺上按照自己的想法來實現對應的需求。

1.自定義需求

使用者可以通過瀏覽器介面訪問Kibana來制定不同的篩選規則,查詢儲存在ElasticSearch叢集中的異常日誌資料。返回的結果在瀏覽器介面通過表格或者JSON物件的形式進行展示,一目瞭然。

2.命令介面

對於週期較長的歷史資料,如果不需要可以進行刪除。在Kibana中提供了操作ElasticSearch的介面,通過執行刪除命令來清理ElasticSearch中無效的資料。

3.結果匯出與共享

在Kibana系統中,分析完異常日誌後可以將這些結果直接匯出或者共享。Kibana的瀏覽器介面支援一鍵式結果匯出與資料分享,不需要額外的去編寫程式碼來實現。

2.1 架構與剖析

搭建實時日誌分析平臺涉及到的元件有ElasticSearch、LogStash、Kibana、Kafka,它們各自負責的功能如下:

  • ElasticSearch:負責分散式儲存日誌資料,給Kibana提供視覺化的資料來源;
  • LogStash:負責消費Kafka訊息佇列中的原始資料,並將消費的資料上報到ElasticSearch進行儲存;
  • Kibana:負責視覺化ElasticSearch中儲存的資料,並提供查詢、聚合、圖表、匯出等功能;
  • Kafka:負責集中管理日誌資訊,並做資料分流。例如,Flume、LogStash、Spark Streaming等。

1.架構

將日誌伺服器託管的壓縮日誌統計收集到Kafka訊息佇列,有Kafka實現資料分流。通過LogStash工具消費Kafka中儲存的訊息資料,並將消費後的資料寫入到ElasticSearch進行儲存,最後通過Kibana工具來查詢、分析ElasticSearch中儲存的資料,整個體系架構如圖10-17所示。

 

 

 

 

資料來源的收集可以採用不同的方式,使用Flume Agent採集資料則省略了額外的編碼工作,使用Java API讀取日誌資訊則需要額外的編寫程式碼來實現。
這兩種方式將採集的資料均輸送到Kafka叢集中進行儲存,這裡使用Kafka主要是方便業務擴充,如果直接對接LogStash,那麼後續如果需要使用Spark Streaming來進行消費日誌資料,就能很方便的從Kafka叢集中消費Topic來獲取資料。這裡Kafka起到了很好的資料分流作用。

 2.模組分析

實時日誌分析平臺可以拆分為幾個核心模組,它們分別是資料來源準備、資料採集、資料分流、資料儲存、資料檢視與分析。在整個平臺系統中,它們執行的流程需要按照固定的順序來完成,如下圖所示。

 

 

a. 資料來源準備
資料來源是由異常壓縮日誌構成的,這些日誌分別由客戶端執行業務邏輯、呼叫服務端介面這類操作產生。然後將這些日誌進行壓縮儲存到日誌伺服器。
b. 資料採集
採集資料來源的方式有很多,可以選擇開源的日誌採集工具(如Apache Flume、LogStash、Beats),使用這些現有的採集工具的好處在於省略了編碼工作,通過編輯工具的配置檔案即可快速使用,缺點在於針對一些特定的業務場景,可能無法滿足。
另外一種方式是使用應用程式設計介面(API)來採集,例如使用Java API讀取待採集的資料來源,然後呼叫Kafka介面將資料寫入到Kafka訊息佇列中進行儲存。這種方式的好處在於對於需要的實現是可控的,缺點在於編碼實現時需要考慮很多因素,比如程式的效能、穩定性、可擴充套件性等。
c. 資料分流
在一個海量資料應用場景中,資料採集的Agent是有很多個的,如果直接將採集的資料寫入到ElasticSearch進行資料儲存,那麼ElasticSearch需要同時處理所有的Agent上報的資料,這樣會給ElasticSearch叢集服務端造成很大的壓力。
因此需要有個緩衝區來緩解ElasticSearch叢集服務端的壓力。這裡使用Kafka來做資料分流,將Agent上報的資料儲存到訊息佇列。然後在通過消費Kafka中的Topic訊息資料後儲存到ElasticSearch叢集中,這樣不僅可以緩解ElasticSearch叢集服務端的壓力,而且還能提高整個系統的效能、穩定性、擴充套件性。
d. 資料儲存
這裡使用ElasticSearch叢集來作為日誌最終的儲存介質。通過消費Kafka叢集中的Topic資料,按照不同的索引(Index)和型別(Type)儲存到ElasticSearch叢集中。
e. 資料視覺化
異常日誌資料落地在ElasticSearch叢集中,可以通過Kibana來實現視覺化功能。使用者可以自定義規則來查詢ElasticSearch叢集中的資料,並將查詢的結果以表格或者JSON物件形式輸出。同時,Kibana還提供了一鍵匯出功能,將這些查詢的結果從Kibana瀏覽器介面匯出到本地。

3.實戰演練

1. 資料來源採集
這裡通過Apache Flume工具將上報的異常日誌資料採集到Kafka叢集進行儲存。在日誌伺服器部署一個Flume Agent進行資料採集,Flume配置檔案所包含的內容見如下程式碼:

# 設定代理別名
agent.sources = s1
agent.channels = c1
agent.sinks = k1

# 設定收集方式                                                                                                                               
agent.sources.s1.type=exec
agent.sources.s1.command=tail -F /data/soft/new/error/logs/apps.log
agent.sources.s1.channels=c1
agent.channels.c1.type=memory
agent.channels.c1.capacity=10000
agent.channels.c1.transactionCapacity=100

# 設定Kafka接收器
agent.sinks.k1.type= org.apache.flume.sink.kafka.KafkaSink
# 設定Kafka的broker地址和埠號
agent.sinks.k1.brokerList=dn1:9092,dn2:9092,dn3:9092
# 設定Kafka的Topic
agent.sinks.k1.topic=error_es_apps
# 設定序列化方式
agent.sinks.k1.serializer.class=kafka.serializer.StringEncoder
# 指定管道別名
agent.sinks.k1.channel=c1

然後在Kafka叢集上使用命令建立名為“error_es_apps”的Topic,建立命令如下所示:

# 建立Topic,3個副本,6個分割槽
[hadoop@dn1 ~]$kafka-topics.sh --create –zookeeper\
 dn1:2181,dn2:2181,dn3:2181 --replication-factor 3\
 --partitions 6 --topic error_es_apps

接著啟動Flume Agent代理服務,具體命令如下所示:

# 在日誌伺服器上啟動Agent服務
[hadoop@dn1 ~]$ flume-ng agent -n agent -c conf -f $FLUME_HOME/conf/flume-kafka.properties\
 -Dflume.root.logger=DEBUG,CONSOLE

2. 資料分流
將採集的資料儲存到Kafka訊息佇列後,可以供其他工具或者應用程式消費來進行資料分流。例如,通過使用LogStash來消費業務資料並將消費後的資料儲存到ElasticSearch叢集中。
如果LogStash沒有按照X-Pack外掛,這裡可以提前安裝該外掛。具體命令如下所示:

# 線上安裝
[hadoop@nna bin]$ ./logstash-plugin install x-pack
# 離線安裝
[hadoop@nna bin]$ ./logstash-plugin install file:///tmp/x-pack-6.1.1.zip

安裝成功後,在Linux控制檯會列印日誌資訊,如下圖所示:

 

 然後,在logstash.yml檔案中配置LogStash的使用者名稱和密碼,具體配置內容見程式碼:

# 使用者名稱
xpack.monitoring.elasticsearch.username: "elastic"
# 密碼
xpack.monitoring.elasticsearch.password: "123456"

最後配置LogStash的屬性,連線到Kafka叢集進行消費。具體實現內容見程式碼:

# 配置輸入源資訊
input{
        kafka{
        bootstrap_servers => "dn1:9092,dn2:9092,dn3:9092"
        group_id => "es_apps"
        topics => ["error_es_apps"]
        }
}

# 配置輸出資訊
output{
        elasticsearch{
        hosts => ["nna:9200","nns:9200","dn1:9200"]
        index => "error_es_apps-%{+YYYY.MM.dd}"
        user => "elastic"
        password => "123456"
  }
}

在配置輸出到ElasticSearch叢集資訊時,索引建議以“業務名稱-時間戳”來進行命名,這樣做的好處在於後續刪除資料的時候,可以很方便的根據索引來刪除。由於配置了許可權認證,索引需要設定使用者名稱和密碼。 配置完成後,在Linux控制檯執行LogStash命令來消費Kafka叢集中的資料。具體操作命令如下所示:

# 啟動LogStash消費命令
[hadoop@nna ~]$ logstash -f $LOGSTASH_HOME/config/kafka2es.conf

如果配置檔案內容正確,LogStash Agent將正常啟動消費Kafka叢集中的訊息資料,並將消費後的資料儲存到ElasticSearch叢集中。 啟動LogStash Agent之後,它會一直在Linux作業系統後臺執行。如果Kafka叢集中Topic有新的資料產生,LogStash Agent會立刻開始消費Kafka叢集中的Topic裡面新增的資料。

3. 資料視覺化
當資料儲存到ElasticSearch叢集后,可以通過Kibana來查詢、分析資料。單擊“Management”模組後,在跳轉後的頁面中找到“Kibana-Index Patterns”來新增新建立的索引(Index)。在新增完成建立的索引後,單擊“Discover”模組,然後選擇不同的索引來查詢、分析ElasticSearch叢集中的資料

4.結束語

這篇部落格就和大家分享到這裡,如果大家在研究學習的過程當中有什麼問題,可以加群進行討論或傳送郵件給我,我會盡我所能為您解答,與君共勉!

另外,博主出書了《Kafka並不難學》和《Hadoop大資料探勘從入門到進階實戰》,喜歡的朋友或同學, 可以在公告欄那裡點選購買連結購買博主的書進行學習,在此感謝大家的支援。關注下面公眾號,根據提示,可免費獲取書籍的教學視訊。

相關文章