有贊統一日誌平臺初探

原文地址https://tech.youzan.com/you-zan-tong-ri-zhi-ping-tai-chu-tan/

一、引言

自有贊成立以來,發展迅猛,業務增長很快,業務系統數量大,每天都會產生大量的系統日誌和業務日誌(據統計,平均每秒產生日誌1.1萬條,峯值1.5萬條,每天的日誌量約9億條,佔用空間2.4T左右)。

在信息化時代,日誌的價值是無窮的。爲了對系統進行有效的監控、維護、優化、改進,都離不開對日誌的收集和分析,而這些日誌散落在各個服務器上,無論對運維同學、還是業務開發同學,抑或是數據部門的同學而言,查閱或分析日誌是一大痛點,實時收集分佈在不同節點或機器上的日誌,供離線或在線查閱及分析來提升工作效率的需求異常迫切,在此背景下,於是有贊統一日誌平臺就應運而生了。

在互聯網高速發展的今天,有那麼多優秀的日誌收集系統,諸如Kafka、Flume、Scribe、Chukwa、ELK等。對於如何選型在此不做討論,而且本人才疏學淺,也未做深入調研和性能分析對比測試,還不夠資格討論。相信前人的選擇是有其理由的,接下來我們來看看秉着“短平快”的互聯網精神,構建的這套適合有贊業務系統的統一日誌平臺。

二、總體設計

廢話不多說,直接上總體架構圖,如圖2-1所示:
總體架構圖
有贊統一日誌系統,負責收集所有系統日誌和業務日誌,轉化爲流式數據,通過flume或logstash上傳到日誌中心(kafka集羣),然後供Track、Storm、Spark及其它系統實時分析處理日誌,並將日誌持久化存儲到HDFS供離線數據分析處理,或寫入ElasticSearch提供數據查詢,或寫入Hawk發起異常報警或提供指標監控查詢。

三、模塊分解

從上面總體架構圖中,我們可以看到整個日誌平臺架構分爲四層,從左到右依次是日誌接入層、日誌中心、日誌處理層、日誌存儲層。

3.1 日誌接入層

日誌接入層主要有兩種方式,方式1基於rsyslog和logstash,方式2基於flume-ng。

3.1.1

在這裏插入圖片描述
對於一些穩定的日誌,比如系統日誌或框架日誌(如nginx訪問日誌、phpfpm異常日誌等),我們添加nginx配置,通過rsyslog寫到本地目錄local0,然後logstash根據其配置,會將local0中的增量日誌上傳到日誌中心對應的topic中,具體數據流圖見圖3-1所示:

3.1.2

Flume NG是一個分佈式,高可用,可靠的系統,它能將不同的海量數據收集,移動並存儲到一個數據存儲系統中。輕量,配置簡單,適用於各種日誌收集,並支持Failover和負載均衡。並且它擁有非常豐富的組件。Flume NG採用的是三層架構:Agent層,Collector層和Store層,每一層均可水平拓展。其中Agent包含Source,Channel和Sink,三者組建了一個Agent。三者的職責如下所示:

Source:用來消費(收集)數據源到Channel組件中,簡單說就是蒐集數據的入口。

Channel:中轉臨時存儲,保存所有Source組件信息,其實就是個消息隊列,可配置多個Chanel。

Sink:從Channel中讀取,讀取成功後會刪除Channel中的信息,簡單說就是蒐集數據的出口。

在有贊日誌平臺中,我們只用了Agent層。具體可以見圖3-2:
在這裏插入圖片描述
日誌中心的kafka是根據topic存取數據的,所以需要在日誌中加入topic字段。爲了統一,我們對日誌格式做了約定,格式如下:

<158>yyyy-MM-dd HH:mm:ss host/ip level[pid]: topic=track.**** {“type”:“error”,“tag”:“redis connection refused”,“platform”:“java/go/php”,“level”:“info/warn/error”,“app”:“appName”,“module”:“com.youzan.somemodule”,“detail”:“any things you want here”}

對於PHP Server,我們在PHP框架中封裝了日誌SDK,PHP開發的同學只需調用寫日誌接口,就可以將日誌傳到Flume中。同樣的,對於Java Server,也封裝了日誌SDK(基於logback自定義了TrackAppender),並集成在Dubbox框架中,業務開發的同學只需在其工程的logback.xml中添加相應的appender配置,指明應用名和日誌topic即可將日誌異步傳到Flume中。對於其它應用或服務(比如基於Go、Node.JS、Python等),如果需要接入日誌平臺,只需按照以上日誌格式組裝日誌,並將其上傳到Flume即可。

細心的同學會發現,在圖3-2中,我們用了TrackSink,這個是做什麼的呢?雖然Flume自帶豐富的組件,也包括KafkaSink,但是爲什麼我們不用呢?考慮到自帶的KafkaSink不能按我們需要的topic來分發數據,所以只能自定義實現了Sink來達到寫不同topic日誌到不同日誌中心topic中去的目的。

另外,Flume是通過Supervisor啓動的,並且添加了監控報警,但是爲了避免日誌寫失敗,在Flume中,我們使用了Failover策略,假如寫日誌中心失敗,則將日誌寫到本地,保證日誌不丟失。

3.2 日誌中心

美其名曰日誌中心,但實際上只是日誌中心緩存,我們只保存最近24小時的日誌,需要持久化的日誌都會刷入HDFS。至於爲什麼選用kafka集羣來構建日誌中心,理由主要如下:

1、分佈式架構,可支持水平擴展。

2、高吞吐量,在普通的服務器上每秒鐘也能處理幾十萬條消息(遠高於我們的峯值1.5萬條/秒)。

3、消息持久化,按topic分區存儲,支持可重複消費。

4、日誌系統不需要保證嚴格的消息準確性。

5、數據在磁盤上的存取代價爲O(1)。

6、可根據broker配置定期刪除過期數據。

3.3 日誌處理層和日誌存儲層

日誌處理層,是我們真正做事的地方;日誌存儲層,則是我們存放日誌分析結果的地方。

基於日誌中心,可做的事情有很多。只要我們對某topic日誌感興趣,那麼便可以將該topic日誌消費來滿足我們的業務需求。我們可以:

1、將日誌聚合,根據業務不同,建立不同的索引,存入ElasticSearch提供查詢。

2、發現異常日誌時,發往監控中心,向對應的業務方發起報警,發現和預發問題的實時性提高了。

3、統計一些訪問日誌或調用日誌等指標信息,發往監控中心來掌握相關調用趨勢。

4、調用鏈開始做起來了,系統性能瓶頸一目瞭然了。

5、用戶日誌行爲可分析了。

這裏我們做了不少,但是需要做的還有更多,就不一一例舉了。

四、遇到的問題和要做的事情

突然接手如此規模的一個基礎產品,遇到的問題還是比較多的:

1、業務日誌接入,每一次對接不僅需要開發日誌消費模塊,解析相應日誌,建立相應的索引並寫入elasticsearch,還需要開發對應定製的查詢頁面。由於自己本身對系統不熟悉,另外文檔缺失,以及每一次對接的都是“新人”,還時不時可能會遇到各種千奇百怪的問題,需要排查定位並解決問題。這塊急需解放,不然一個人真的忙不過來,針對該問題,接下來會抽象出日誌消費和elasticsearch讀寫SDK,供業務接入方自己開發和維護。

2、對於各個組件(如logstash、flume、kafka、elasticsearch等)都未曾接觸過的情況下,短時間接手這麼一個新產品,需要學習的東西很多,壓力還是很大的,但總算熬過來了。

3、缺失的開發測試環境,到寫此文章時總算搭建起來了。

4、elasticsearch內存佔用高,以及索引的管理與維護,還在優化和考慮中。

5、需要開發更加人性化且更易擴展和維護的運控平臺供使用方查詢日誌。

6、日誌收集到Flume增加支持UDP協議。

7、將存儲層的HDFS移到日誌中心,支持日誌同時寫入Kafka集羣和HDFS集羣。

8、是時候做點日誌挖掘的事情了。

五、結語

爲什麼做這次分享?

由於之前交接時間較短,實際只有2天,然後統一日誌平臺涉及的內容比較多,接手日誌平臺的這一個多月是痛苦的,然後找崔(有贊CTO)吐槽了一下。結果崔知道我在梳理日誌平臺,就讓我順便寫篇介紹有讚的日誌架構的文章,幫助大家瞭解一下。怎奈我這人臉皮太薄,在對日誌平臺還不熟悉的情況下,竟然應承下來了,俗話說的好,死要面子活受罪。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章