“淘寶京東”構建流式計算賣家日誌系統架構的應用實踐

Java高階開發發表於2018-04-28

摘要: 萬變不離其宗

引言

本文給大家講述的是我們如何去構建一個日誌系統,用到了那些技術,為什麼用這些技術,並且講述了遇到的問題及優化的過程,希望給大家在實踐中能夠提供一些參考。

最近在維護一個有關於日誌的專案,這個專案是負責收集、處理、儲存、查詢京東賣家相關操作的日誌,我們這裡就叫它“賣家日誌”。在日常的開發過程中,可能我們對日誌這個詞並不陌生,例如我們常接觸到的log4j、slf4j等等,這些日誌工具通常被我們用來記錄程式碼執行的情況,當我們的系統出了問題時,我們可以通過檢視日誌及時的定位問題的所在,從而很快的解決問題,今天我所講的賣家日誌,又與這個有些許的不同,賣家日誌是用來記錄賣家對系統各個功能的操作情況,例如:張三這個商家對它的店鋪的某款商品進行了價格的修改。這樣在我們這就會記錄下一條日誌在我們的系統當中,在這個系統中的部分資訊我們是可以提供給商家、運營人員看,從而讓商家知道自己做了哪些操作,也讓運營人員更好的對商家進行管理,除此之外,也可以幫忙查詢從log中找不到的資訊,從而幫助開發人員解決問題。其他的不多說,接下來就講一下我們的業務場景。

業務場景

我們有許多的業務系統,如訂單、商品,還要一些其他的系統,之前,大家都是各自記錄各自的日誌,而且記錄的方式五花八門,格式也獨具一格,而對於商家和運營人員來說這是非常頭疼的一件事,沒有給運營人員提供一個可以查詢日誌的平臺,每次有問題的時候,只能耗費大半天的時間去找對應的開發團隊,請他們配合找出問題所在,而且有的時候效果也不是很好。在這麼一種情況下,賣家日誌就誕生了,它給商家和運營以及開發提供了一個統一的日誌平臺,所有團隊的日誌都可以接入這個平臺,通過申請許可權,並且運營和商家有問題可以第一時間自己去查詢日誌解決問題,而不是盲目的找人解決。

日誌總體設計

這裡寫圖片描述

圖是這個日誌系統總體的整體流程圖,在對於處理日誌這一塊業務上,我們寫了一個日誌客戶端提供給各個組呼叫,還用到了kafka+Strom的流式計算,對於日誌查詢這一塊,我們首先想到了ES,因為ES是一個分散式的檔案檢索系統,它可以根據日誌的內容提供豐富的檢索功能,而對於冷日誌的儲存,我們用到了一個能夠存更大量的工具—HBase,並且也可以根據一些基本的條件進行日誌的搜尋。

流程:日誌客戶端 - Kafka叢集 - Strom消費 - ES -HBase - …

技術點

Kafka:Kafka是一種高吞吐量的分散式釋出訂閱訊息系統,它可以處理消費者規模的網站中的所有動作流資料,說淺顯易懂一點,我們可以將Kafka理解成為一個訊息佇列。

Storm:Storm是開源的分散式實時大資料處理框架,它是實時的,我們可以將它理解為一個專門用來處理流式實時資料的東西。

ElasticSearch:ES是一個基於Lucene的搜尋伺服器,它是一個分散式的檔案檢索系統,它給我們提供了高效的檢索,以及支援多種檢索條件,用起來也十分方便。

HBase:HBase是一個高可靠性、高效能、面向列、可伸縮的分散式儲存系統,適用於結構化的儲存,底層依賴於Hadoop的HDFS,利用HBase技術可在廉價PCServer上搭建起大規模結構化儲存叢集。

日誌客戶端

日誌客戶端給各個系統提供了一個統一的Api,就類似於Log4j這些日誌工具一樣,這樣使得接入變得方便簡潔,就和平常寫日誌沒什麼區別。這裡需要提到的一個點是客戶端對於日誌的處理過程,下面我用圖來給大家進行說明,如下圖:
這裡寫圖片描述

大家可能會疑惑,為什麼不直接寫Kafka呢?那麼接下來我給大家做個比較,直接寫入本地快,還是寫Kafka快呢?很明顯,寫入本地快。因為寫日誌,我們想達到的效果是儘量不要影響業務,能夠以更快的方式處理的就用更快的方式處理,而對於日誌後期的處理,我們只需要在後臺開啟固定的幾個執行緒就可以了,這樣既使的業務對此無感知,又不浪費資源,除此之外,落盤的方式還為日誌資料不丟提供了保障。

此外,這裡本地資料的落盤和讀取都用到了Nio的記憶體對映,寫入和讀取的資料又有了進一步的提升,使得我們的業務日誌快速落盤,並且能夠快速的讀取出來傳送到Kafka。這也是這一塊的優勢。

為什麼要用Kafka

首先給大家介紹一下Kafka,其實網上也有很多的例子,接下來我說一下我對Kafka的理解吧,有不對的地方還請大家及時指正。Kafka是一種高吞吐量的分散式釋出訂閱訊息系統,它可以處理消費者規模的網站中的所有動作流資料,說淺顯易懂一點,我們可以將Kafka理解成為一個訊息佇列。具體的一些細節,大家可以上網搜尋。

Kafka主要應用場景中:

持續的訊息:為了從大資料中派生出有用的資料,任何資料的丟失都會影響生成的結果,Kafka提供了一個複雜度為O(1)的磁碟結構儲存資料,即使是對於TB級別的資料都是提供了一個常量時間效能。

高吞吐量:keep big data in mind,Kafka採用普通的硬體支援每秒百萬級別的吞吐量

分散式:明確支援訊息的分割槽,通過Kafka伺服器和消費者機器的叢集分散式消費,維持每一個分割槽是有序的。

支援多種語言:Java、.net、PHP、ruby、Python。

實時性:訊息被生成者執行緒生產就能馬上被消費者執行緒消費,這種特性和事件驅動的系統是相似的。

Kafka的優勢:

主要是用來解決百萬級別的資料中生產者和消費者之間資料傳輸的問題

可以將一條資料提供給多個接收這做不同的處理

當兩個系統是隔絕的,無法通訊的時候,如果想要他們通訊就需要重新構建其中的一個工程,而Kafka實現了生產者和消費者之間的無縫對接。

通過上面對Kafka的應用場景和優勢的描述,我們再去理解我們的日誌的業務場景,就能理解我們為什麼採用的技術是Kafka了。因為Kafka快,並且適用於流式處理,它可以將突發的量轉換成為平穩的流,以便於我們Strom的處理。至於為什麼快,我在這就不給大家詳解了。因為日誌是不定時的,就像水流一樣,一直是不斷的,並且不一定是平穩的。而Kafka的一些特性,非常符合我們日誌的業務,除此之外,Kafka作為一個高吞吐量的分散式釋出訂閱訊息系統,可以有多個生產者和消費者,這也為我們的日誌統一接入和後期的多元化處理提供了強有力的保障。如下圖:
這裡寫圖片描述

Storm的應用

前面也介紹了,日誌是一個流式的資料,它是不定時的,而且是不平穩的,我們需要將這些不定時且不平穩的資料進行處理,用什麼方式更好呢?我們在這一塊進行了一場討論,而最終我們採用了Kafka+Storm的方式來處理這些日誌資料。Kafka我就不過多介紹了,前面講了。為什麼要用Storm呢?對於Storm,我想大家應該有所瞭解,Storm是一個免費開源、分散式、高容錯的實時計算系統。Storm令持續不斷的流計算變得容易,我們看重的就是它的流式計算的能力。Kafka可以將突發的資料轉換成平穩的流,源源不斷的推向Storm,Storm進行消費,處理,最終落庫。下面我簡單的畫一下Storm處理這一塊的流程,如下圖所示:
這裡寫圖片描述

從上圖我們可以看到Storm整個一個處理的流程,其中我們對日誌進行了兩次的處理,一次是校驗是否有效,並且封裝成物件交給下一個bolt,insertBolt負責將資料落庫,這麼一個流程看起來比較清晰明瞭。

針對上面的技術我特意整理了一下,有很多技術不是靠幾句話能講清楚,所以乾脆找朋友錄製了一些視訊,很多問題其實答案很簡單,但是背後的思考和邏輯不簡單,要做到知其然還要知其所以然。如果想學習Java工程化、高效能及分散式、深入淺出。微服務、Spring,MyBatis,Netty原始碼分析的朋友可以加我的Java進階群:697579751,群裡有阿里大牛直播講解技術,以及Java大型網際網路技術的視訊免費分享給大家。

關於資料儲存的處理

對於資料的儲存,從上面我們可以知道我們用的ES來對熱資料進行儲存,而對於冷資料,也就是很久之前的資料,我們採用HBase來進行儲存備份。為什麼要這樣做呢,下面我給大家說一下這樣做的原因。

日誌資料使用什麼樣東西做儲存,直接影響這我們的查詢,前期我們的想法是直接把資料存到能夠抗量HBase上,但是對於多種條件的查詢,HBase顯然不符合我們的要求,所以經過評審,決定用一個分散式檢索的系統來進行儲存,那就是ElasticSearch。那大家可能會問到:為什麼還要用HBase呢?因為ES作為一個檢索的系統,它並不適用於大量的資料的儲存,隨著資料量的增大,ES的查詢效能會慢慢的降低,而我們的日誌需要儲存的時間是一年,每天的量都是6、7億的資料,所以對於ES來說,很難抗住,不斷的加機器並不是很好的解決辦法。經過討論,我們想用一個更能夠存資料的東西來存很久不用的日誌資料,並且能夠提供簡單的檢索,我們想到了HBase,將最近兩個月的資料放在es中,給使用者提供多條件的檢索,兩個月之前的資料我們存放在HBase中,提供簡單的檢索功能,因為兩個多月前的日誌也沒有太大的量去檢視了。具體的資料流轉如下圖:
這裡寫圖片描述

遇到的問題

隨著資料量的增多,對我們服務的要求要來越高了,我們發現,即使是將儲存的資料做了冷熱分離,查詢也非常的忙,並且隨著資料量的增多,插入的效能也越來越慢了。而且,對於我們所申請的Kafka叢集,明顯也扛不住這麼多客戶端每天輸入這麼大的量,因為這些問題,我們放慢了腳步,對日誌這一塊的業務流程進行了仔細的梳理。

解決方案

經過不斷的討論和架構的評審,我們想到了一個比較好的解決辦法,那就是對日誌資料進行業務分離。我們抽出了幾個日誌量比較大的業務,比如訂單和商品,我們新申請了訂單和商品的Kafka叢集和ES叢集,其他一些業務還是不變,訂單和商品的日誌和其他日誌都單獨開來,使用不同的Kafka和ES、HBase叢集。我們通過對業務的抽離,效能得到了很明顯的提升,並且對資料進行業務的分類,也方便了我們對日誌資料的管理,達到互不影響的狀態。今後對於HBase的資料,我們也打算將它推入到大資料集市中,提供不同的部門做資料分析。

結語

上面我們將日誌的一整套流程都給大家描述了一遍,有一些細節方面的東西沒有詳細的去講解,就比如說日誌傳送的監控,日誌的鑑權,日誌的許可權管理等等,主要的是講述了整體的架構。也許這個架構不是最優的,但是對於一個系統而言,一開始系統的強大一定不是一蹴而就的,而是經過不斷的壯大,發現問題,解決問題,不斷的完善,從而達到一個最優的狀態

針對上面的技術我特意整理了一下,有很多技術不是靠幾句話能講清楚,所以乾脆找朋友錄製了一些視訊,很多問題其實答案很簡單,但是背後的思考和邏輯不簡單,要做到知其然還要知其所以然。如果想學習Java工程化、高效能及分散式、深入淺出。微服務、Spring,MyBatis,Netty原始碼分析的朋友可以加我的Java進階群:697579751,群裡有阿里大牛直播講解技術,以及Java大型網際網路技術的視訊免費分享給大家。
這裡寫圖片描述
歡迎關注

相關文章