1. 程式人生 > 其它 >分散式日誌儲存架構設計方案

分散式日誌儲存架構設計方案

在一個完整的專案中,不僅僅是要完成正常的業務開發。同時為了提高一些開發效率、系統異常的追蹤、系統功能的擴充套件等等因素,往往會用到系統在開發、執行過程中所產生的日誌。這就需要我們有一個完善的日誌系統來儲存這些資料。本文將分享如何設計一個高可用、可擴充套件的分散式日誌系統。

  1. 本文是一種理論性的方案探索,當然各種方案也是在實際的生產環境中經過實踐總結而來的。
  2. 本文是分散式日誌儲存系列的理論篇。也有實戰篇,將會分享從0到1的整個過程,從0環境的搭建到真正的實踐落地。文章會定期的完善,最終文章地址

日誌的重要性

在一個系統中,日誌常常在下面的一些場景中佔著非常大的作用:

  1. 專案開發階段的除錯、線上服務異常排查。
  2. 系統異常的監控。
  3. 系統資料分析。

對應日誌,主要分為下面三大型別:

日誌服務的演進

通過上面幾點,大致明白了一個日誌系統的重要性。接下來,我們將進一步瞭解如何設計一個日誌系統。

單節點部署

在專案早期,由於專案使用者量小業務資料少等特點,一般專案都會採用單節點的方式進行部署。此時的日誌,一般會以檔案的方式儲存在對應伺服器上。如下圖:

當客戶端向服務端傳送請求,對應的伺服器處理業務並將日誌記錄到日誌檔案中。這也是傳統的日誌記錄方式,很多的後端框架預設的日誌記錄方式也如此。如下面PHP的Hyperf框架,預設將MySQL的操作日誌記錄到日誌檔案中。

優點

按照這種傳統的單節點部署,有什麼好處呢?

  1. 系統架構單一、部署簡單。不用擔心各種服務之間呼叫問題。
  2. 技術成本低、易維護。直接使用開發語言的檔案操作函式,寫人即可。
  3. 效能高、穩定。不需要呼叫其他的服務元件,直接呼叫系統介面寫入磁碟即可。

缺點

  1. 當日志文件過大時,需要對日誌檔案做切割,避免寫入效能降低。
  2. 不便於日誌排查。對應開發人員來說,可以直接分析日誌內容。如果對於非開發人員來說,對日誌儲存的就有一定的要求。
  3. 存在安全問題。對應伺服器一般都有設定許可權,需要對伺服器使用者設定嚴格的許可權。

分散式部署(檔案)

這裡的分散式部署(檔案)指的是,系統服務採用分散式部署時,日誌儲存還是採用檔案儲存。大致的邏輯圖如下:

優點

  1. 這樣的部署方案有什麼好處,和上面提到的單節點部署一樣。

缺點

  1. 在分散式部署中,還是同樣的會遇到單節點部署所遇到的問題。
  2. 不便於系統排查。當系統出現異常時,由於是分散式部署,我們不知道最終的日誌儲存在那一臺伺服器上,就需要挨個伺服器的排查。降低了問題排查效率。

分散式部署(日誌系統)

上面提到了分散式系統,使用檔案儲存日誌的幾個弊端。因此這裡推出使用獨立的日誌系統,儲存系統日誌。大致邏輯圖如下:

  1. 當客戶單傳送請求到伺服器,伺服器處理對應的業務邏輯和記錄日誌服務。
  2. 為了提高系統的響應速度、高可用,在記錄日誌時,先將日誌寫入到MQ訊息佇列中,開啟獨立的執行緒將佇列中的日誌寫入到磁碟中。常見的MQ訊息佇列有,RabbitMQ,RocketMQ,ActiveMQ,ZeroMQ,Kafka,IBM WebSphere等。可以根據系統的實際需要選擇合適的MQ服務。
  3. 寫入對應的日誌系統之後,可以獨立開發一套系統,來做日誌的顯示、查詢、刪除等操作。

優點

  1. 解決了分散式部署中採用檔案儲存的弊端。
  2. 提高了系統的可用性。在寫日誌時,開發人員只需要將日誌寫入到對應的MQ訊息佇列中即可。做持久化直接讓單獨的執行緒執行。
  3. 提高了系統的擴充套件性。如果團隊中,其他的專案需要增加日誌功能,我們不需要單獨的增加伺服器,直接寫入原有的MQ訊息佇列系統即可。

缺點

  1. 系統部署複雜。增加了MQ服務,也意味著在專案前期增加了運維成本。
  2. 對開發人員要求高。需要熟悉MQ訊息服務技術棧。
  3. 系統架構要求高。在專案前期一定要搭建一個高可用、高擴充套件的架構,當業務變得越來越複雜時以及各種服務之間的呼叫,影響正常的業務邏輯。

日誌系統

上面針對日誌服務做了一個架構演進的總結。接下來,就來具體的探討如何設計一個高可用、高擴充套件的日誌系統。
對應日誌系統,我個人如下幾個觀點:

  1. 可用性強,不能影響正常業務的執行。日誌的作用最大的意義在於我們排查問題、分析問題以及解決問題。要保證在這個過程中,即使日誌服務不可用的狀態下,仍然不能影響到正常業務的日誌。
  2. 擴充套件性強。在設計日誌系統時,不能只針對當前的系統做設計,還需要考慮到後期其他專案日誌的接入。

針對日誌系統,我們可以採用自研的方式,也可以採用開源系統部署。在本文總,分享兩種較為簡單的日誌服務系統。大致的邏輯圖如下:

MongoDB儲存

系統日誌最終的落地,肯定是磁碟。因此,第一種方案我們使用MongoDB來記錄日誌。
為什麼採用MongoDB作為日誌儲存伺服器呢?

  1. MongoDB嚴格來說是一個非關係型的資料庫系統。它支援的資料結構非常鬆散,類似json格式的bson格式,因此可以儲存比較複雜的資料型別。如果採用MySQL、SQLserver、oracle這樣的具有嚴格資料結構要求的資料庫,在日誌統計緯度變化時,對應的資料表結構也會隨著變化。
  2. 查詢效率高。MongoDB最大的特點是它支援的查詢語言非常強大,其語法有點類似於面向物件的查詢語言,幾乎可以實現類似關係資料庫單表查詢的絕大部分功能,而且還支援對資料建立索引。
  3. 業務拆分、提高業務資料庫效能。如果把日誌也儲存在MySQL中,必然會降低MySQL的高併發效能問題。一個系統中,日誌內容肯定非常的多,日誌的讀寫搶佔了對應的操作必然是會降低業務讀寫的操作。

使用MongoDB作為日誌儲存服務,大致的邏輯可以採用如下結構:

  1. 業務系統處理日誌,再呼叫MQ訊息服務,先將日誌資料存在MQ訊息服務中。
  2. 開啟非同步執行緒,將MQ服務的訊息同步到MongoDB服務中,以達到持久化的目的。
  3. Web頁面則是用於日誌資料的展示。

ELK儲存

​ ELK是Elasticsearch+Logstash +Kibana 這種架構的簡寫。​ 這是一種開源日誌分析平臺的架構。ELK是開源的,社群活躍,使用者眾多,這樣的架構也得到廣泛的使用。大致的邏輯圖如下:

ELK常用架構

  1. Elasticsearch + Logstash + Kibana
    這是一種最簡單的架構。這種架構,通過logstash收集日誌,Elasticsearch分析日誌,然後在Kibana(web介面)中展示。這種架構雖然是官網介紹裡的方式,但是往往在生產中很少使用。

  2. Elasticsearch + Logstash + filebeat + Kibana
    與上一種架構相比,這種架構增加了一個filebeat模組。filebeat是一個輕量的日誌收集代理,用來部署在客戶端,優勢是消耗非常少的資源(較logstash), 所以生產中,往往會採取這種架構方式,但是這種架構有一個缺點,當logstash出現故障, 會造成日誌的丟失。

  3. Elasticsearch + Logstash + filebeat + redis(也可以是其他中介軟體,比如kafka(叢集化)) + Kibana這種架構是上面那個架構的完善版,通過增加中介軟體,來避免資料的丟失。當Logstash出現故障,日誌還是存在中介軟體中,當Logstash再次啟動,則會讀取中介軟體中積壓的日誌。目前我司使用的就是這種架構,我個人也比較推薦這種方式。

總結

  1. 對於上面提高的幾種方案,在實際過程中,還需要結合自身的專案情況,選擇合適的架構,而不是為了追求技術的複雜度而忽略了自身的實際情況。

  2. 關於分散式日誌的理論在這裡就介紹結束了,接下來的內容將實戰演示分散式日誌設計方案。感興趣的可以持續關注。對於文章提到的方案,存在不足的地方,也歡迎大家指教。