返回文章列表

平行分散式系統日誌記錄最佳實踐

本文探討在平行與分散式系統中有效記錄日誌的最佳實踐,涵蓋識別資訊、條件式日誌記錄、結構化日誌、敏感資訊處理以及監控、指標和警示的重要性。文章以 Python 日誌記錄為例,說明如何提升日誌效率、降低系統除錯難度,並確保系統的可靠性和可維護性。

系統設計 Web 開發

在分散式和平行處理系統中,日誌記錄的策略需要調整以適應多執行緒和多程式的環境。有效記錄日誌對於系統除錯、效能分析和問題追蹤至關重要。本文將探討如何在平行環境下有效地記錄日誌,並介紹一些最佳實踐,例如使用識別資訊、條件式日誌記錄和結構化日誌等技術。此外,文章也將討論監控、指標和警示在確保系統穩定性和可靠性方面的重要性,並提供一些實用的建議。

有效的記錄日誌(Effective Logging)

在建立可平行執行的系統時,無論是在分散式系統還是在平行處理環境中,都需要重新考慮如何進行日誌記錄(logging),與集中式環境下的記錄方式有所不同。

平行環境中的日誌記錄挑戰

當多個程式或工作執行緒平行執行時,日誌訊息需要包含一些識別資訊,以幫助確定日誌事件所指的內容。以之前的Python日誌記錄為例,注意到在有關物種提取的日誌訊息中包含了user_id

logger.debug("Finished extracting species for user %s. Species extracted: %s", user_id, species)
logger.debug(f"Finished extracting species for user {user_id}. Species extracted: {species}")

內容解密:

  1. 使用 %s 與 f-strings 的差異

    • 使用 %s 的方式會將變數作為引數傳遞給 logger.debug 方法,只有在日誌級別符合條件時才會進行字串插值。
    • 使用 f-strings 時,無論日誌級別如何,日誌訊息都會在呼叫 logger.debug 之前被插值。
  2. 效能考量

    • 在日誌級別設定高於 DEBUG 的環境中,使用 %s 的方式可以避免不必要的字串建立,從而提高效能。

最佳實踐:條件式日誌記錄

Python 日誌記錄中提到的另一項最佳實踐是條件式日誌記錄(conditional logging)。這種技術只有在滿足特定條件時才會發出日誌,這是一種限制主要用於幫助除錯失敗的日誌的好方法。

if logger.isEnabledFor(logging.DEBUG):
    logger.debug("Detailed debug message: %s", some_expensive_computation())

內容解密:

  • 條件檢查:透過檢查 logger.isEnabledFor(logging.DEBUG),只有在 DEBUG 級別被啟用時才會執行 some_expensive_computation() 並記錄日誌。
  • 效能最佳化:這種方式避免了在非 DEBUG 級別下執行耗時的運算,從而最佳化效能。

日誌訊息的結構化

除了控制日誌數量外,日誌訊息的結構也很重要。使用 JSON 格式記錄日誌可以讓你使用如 Google BigQuery 等工具查詢日誌,提供另一種觀察系統行為的方式。

{
  "timestamp": "2023-10-01T12:00:00Z",
  "level": "DEBUG",
  "message": "Finished extracting species",
  "user_id": "abc",
  "batch_id": 1,
  "record_id": "1-1",
  "species_extracted": "night heron"
}

圖表翻譯:

此圖示呈現了日誌訊息的 JSON 結構,包括時間戳、日誌級別、訊息內容以及相關的資料識別碼,有助於查詢和分析。

識別資訊的重要性

在日誌訊息中包含識別資訊(如 user_idbatch_idrecord_id)對於除錯問題至關重要。

logger.debug("Finished extracting species for user %s, batch %d, record %s. Species extracted: %s", user_id, batch_id, record_id, species)

內容解密:

  1. user_id:識別使用者。
  2. batch_id:識別批次。
  3. record_id:識別記錄。
  4. species_extracted:提取的物種。

這些資訊有助於在多個平行執行的任務中定位特定問題。

敏感資訊處理

在處理資料時,避免將敏感資訊記錄到日誌中非常重要。可以透過資料遮罩(data masking)技術來處理敏感資料,但更建議與公司的安全或法律團隊合作,確保合規。

監控資料管道:指引前進方向

在沒有監控資料的情況下操作分散式系統,就像試圖在沒有GPS導航裝置或針的情況下走出森林一樣困難。

缺乏監控的代價

缺乏監控使得除錯、最佳化和擴充套件資料管道變得非常困難和昂貴。就像搜尋和救援隊伍必須被派遣去尋找迷路的徒步旅行者一樣,您將花費大量的工程時間和計算資源來彌補監控不足。

案例分析:缺乏監控的挑戰

曾經,我所在的資料平台團隊只有AWS EMR日誌和一些資源監控工具可用。當一個程式耗盡資源時,我們很幸運地能夠得到描述性的日誌訊息,提示我們發生了什麼。很多時候,我們得到的訊息不僅沒有描述資源短缺的問題,反而讓我們以為是其他問題,例如“無法繫結到地址”。

在根據EMR的資料平台上,大型資料引入作業會定期失敗,嘗試從其中一個叢集節點檢索資料塊。什麼是“大型”引入作業?我們的團隊沒有監控資料量,因此不清楚是什麼原因導致了這個問題。

通常,當故障發生時,值班工程師必須在叢集指標消失之前檢查它們。例如,我們懷疑自動擴充套件事件與這些故障有關,但沒有監控,我們只能透過EMR控制檯存取自動擴充套件事件,而該控制檯只保留最近的事件。如果關鍵的時間點發生在太久以前,它就不會再出現在控制檯中。

此外,這些作業可能執行數小時,卻在浪費半天的計算資源後失敗。唯一的補救措施是重新啟動具有更多容量的作業。

監控的重要性

監控提供了系統執行的資訊。根據這些資訊採取行動,您才能真正從監控中獲得價值。本章將提供有關如何在不同級別的管道可觀察性上進行監控、指標和警示的具體建議。

系統級監控

系統級監控提供了高層次的檢視,可以幫助您瞭解管道的整體效能和資源利用率。

資源利用率監控

資源利用率監控可以幫助您瞭解管道中資源的使用情況,例如CPU、記憶體和磁碟空間。

管道效能監控

管道效能監控可以幫助您瞭解管道的執行效率,例如處理速度和延遲。

查詢成本監控

查詢成本監控可以幫助您瞭解查詢的成本,例如查詢時間和資源消耗。

採取行動

有了監控資料,您就可以採取行動來最佳化管道的效能、降低成本並提高可擴充套件性。例如,您可以根據監控資料調整資源分配、最佳化查詢或改進管道設計。

示例:根據監控資料採取行動

透過監控資料,我們發現了一個最佳化機會:調整自動擴充套件策略以減少資源浪費。根據監控資料,我們還發現了一個效能瓶頸:最佳化查詢以減少延遲。

監控、指標和警示的重要性

在資料處理和分析的過程中,監控、指標和警示是確保系統可靠性和成本效益的關鍵要素。本文將探討缺乏監控機制所帶來的問題,並介紹如何透過實施適當的監控和警示機制來改善系統的整體表現。

缺乏監控的代價

在一個資料處理專案中,由於缺乏適當的監控機制,團隊面臨了多個挑戰。這些挑戰包括:

  • 無法有效診斷問題根源,因為缺乏對任務執行時間、資源利用率和資料量的監控。
  • 對叢集組態的變更缺乏依據,導致資源浪費或任務失敗。
  • 由於資料大小和叢集大小未被監控,導致為較小的任務過度組態資源,造成資金浪費。

這些問題使得團隊如同在沒有地圖、針或GPS的情況下進行探險,完全依靠猜測和經驗來進行問題排查。

監控、指標和警示的定義

  • 指標(Metrics):離散的值,可以從服務中匯出或自定義產生,如 RabbitMQ 的訊息發布率或批次處理任務啟動時的資料量指標。
  • 監控(Monitoring):匯總指標以觀察行為隨時間變化的過程。例如,監控訊息發布率可以幫助識別發布率異常的問題。
  • 警示(Alerting):利用指標和監控結果來通知重要的事件或資訊。警示可以是日常摘要報告,也可以是警告或關鍵故障的通知。

實施監控和警示的好處

實施適當的監控和警示機制可以帶來多方面的好處:

  1. 最佳化資源利用:透過監控任務指標(如資料量、叢集組態、任務執行時間、資源利用率等),可以動態調整叢集大小,以避免過度組態或資源不足。
  2. 提高系統可靠性:及時的警示機制可以幫助團隊在問題發生前採取行動,從而提高系統的可靠性和客戶信任度。
  3. 降低成本:透過精準組態資源和減少重複執行的失敗任務,可以顯著降低工程成本和雲資源成本。

關鍵任務指標

對於資料處理管道來說,以下指標對於提高系統彈性、客戶信任度和成本效益至關重要:

  • 任務指標:資料量、叢集組態、任務執行時間、資源利用率和任務成功/失敗率。
  • 動態叢集調整:根據過去相似大小任務的資源需求動態調整叢集大小。
  • 與使用者分享指標:與使用者分享系統吞吐量(資料量除以任務執行時間)和成功率,以提高透明度和信任度。
內容解密:

本文主要探討了缺乏監控機制對資料處理專案帶來的負面影響,包括無法有效診斷問題、資源浪費和客戶信任度下降。接著,文章定義了監控、指標和警示的概念,並強調了實施這些機制對於最佳化資源利用、提高系統可靠性和降低成本的重要性。最後,文章提出了關鍵任務指標,並結論認為適當的監控和警示機制對於資料驅動組織至關重要。

圖表翻譯:

此圖示展示了監控、指標和警示之間的關係。其中,指標是基礎,透過監控匯總這些指標,可以觀察系統行為隨時間的變化。警示則是根據這些監控結果,用於通知重要的事件或資訊。

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333

title 圖表翻譯:

rectangle "匯總" as node1
rectangle "觸發" as node2

node1 --> node2

@enduml

圖表翻譯: 此圖示呈現了監控、指標和警示之間的邏輯關係。首先,系統會收集各種指標;接著,透過監控這些指標來觀察系統行為的變化;最後,當某些條件被觸發時,系統會發出警示,以通知相關人員進行處理。這個流程有效地幫助團隊及時發現並解決問題,提高了系統的可靠性和效率。

監控在資料管道中的重要性

在前面的章節中,我們看到了一個由於缺乏監控而導致的資料處理問題的例子。團隊在處理過程中遇到了許多問題,包括磁碟使用率過高、自動擴充套件事件和資料匯入失敗。幸運的是,透過監控相關的指標,可以及早發現這些問題並採取相應的措施。

系統監控

系統監控是導航資料管道操作的基礎地圖。如同圖11-1所示,系統監控幫助我們瞭解管道效能的基本情況,例如典型的資料量和平均作業執行時間。這些基準條件為我們提供了識別異常的參考,例如更高的資料量和更長的執行時間。這些異常可以是效能、擴充套件和可靠性的重要訊號。

資料量監控

在第1章中,HoD團隊擁有整年的調查資料,如圖11-2所示,用於估計資料匯入作業的大小。類別似地,監控資料量隨時間的變化將有助於我們改進和重新設計管道資源,以滿足不斷變化的需求。

圖表翻譯:圖11-2展示了每月調查資料量的變化趨勢

此圖示呈現了鳥類別調查活動在不同月份的資料量變化。可以觀察到,從12月到2月的資料量非常低,而9月到10月的資料量達到峰值。假設這種趨勢在往年的資料中也存在,那麼就可以據此進行預算和選擇合適的定價計劃。

監控原始資料量也可以幫助我們追蹤潛在的系統問題;突然的、意外的資料量下降可能指向導致資料丟失的錯誤。另一方面,突然的資料量激增可能會使提供的計算資源不堪重負。

import matplotlib.pyplot as plt

# 假設 data_volume 是一個包含每月資料量的列表
data_volume = [100, 120, 110, 130, 105, 125, 115, 140, 150, 160, 145, 135]

# 繪製每月資料量的變化趨勢
plt.plot(data_volume)
plt.xlabel('月份')
plt.ylabel('資料量')
plt.title('每月資料量變化趨勢')
plt.show()

內容解密:

上述程式碼使用matplotlib函式庫繪製了每月資料量的變化趨勢圖。首先,我們匯入了matplotlib.pyplot模組。然後,假設我們有一個包含每月資料量的列表data_volume。接著,我們使用plt.plot()函式繪製了資料量的變化趨勢,並增加了x軸標籤、y軸標籤和標題。最後,使用plt.show()函式顯示了圖表。

監控資料在管道中的流動過程是另一個檢查問題的地方。例如,假設有一個過濾步驟,預計會消除20%的原始資料。如果觀察到離開過濾步驟的資料量比原始資料量低60%,那麼可能存在過濾邏輯中的錯誤。

吞吐量監控

透過監控資料量,我們還可以監控吞吐量,即在給定時間內處理的資料量。監控管道處理資料的速度可以讓我們提前瞭解效能變化、系統穩定性和擴充套件機會。

對於批次管道,可以根據作業持續時間來衡量吞吐量。回到我在“迷失在森林中”一節中描述的場景,如果我們的團隊當時能夠監控吞吐量,那麼就可以提前發現問題並採取相應的措施。

系統監控:資料管道效能監測與最佳化

在資料工程領域中,監控資料管道的效能對於確保系統穩定性和滿足服務水準協定(SLA)至關重要。本篇文章將探討如何透過監測吞吐量和消費者延遲(Consumer Lag)來識別和解決資料管道中的效能問題。

監測吞吐量

吞吐量是指單位時間內處理的資料量,是評估資料管道效能的關鍵指標。透過監測吞吐量,可以及時發現系統中的瓶頸並進行最佳化。

案例分析

假設某團隊使用 EMR(Elastic MapReduce)進行資料處理,但隨著資料量的增加,作業執行時間顯著延長,最終導致作業失敗。圖 11-3(A) 展示了資料量與作業執行時間的關係,可以觀察到當資料量超過某個閾值後,作業執行時間急劇增加。

作業 ID資料量(TB)執行時間(小時)吞吐量(TB/hr)吞吐量變化(%)資料量變化(%)
11.840.55
22.04.20.48-1411
32.260.37-3010
42.4110.22-689

從表 11-1 中可以看出,隨著資料量的線性增加,吞吐量卻呈現出顯著的下降趨勢。如果團隊能夠及時監測吞吐量,就可以提前發現問題並採取相應措施。

程式碼範例:計算吞吐量

def calculate_throughput(data_volume, job_duration):
    """
    計算吞吐量
    
    :param data_volume: 資料量(TB)
    :param job_duration: 作業執行時間(小時)
    :return: 吞吐量(TB/hr)
    """
    throughput = data_volume / job_duration
    return throughput

# 範例資料
data_volumes = [1.8, 2.0, 2.2, 2.4]
job_durations = [4, 4.2, 6, 11]

# 計算吞吐量
throughputs = [calculate_throughput(data_volumes[i], job_durations[i]) for i in range(len(data_volumes))]

#### 內容解密:
此程式碼定義了一個函式 `calculate_throughput` 用於計算吞吐量函式接受兩個引數:`data_volume`(資料量`job_duration`(作業執行時間),並傳回計算出的吞吐量範例中我們使用列表推導式計算了每個作業的吞吐量

監測消費者延遲

在串流資料管道中,消費者延遲是指生產者生產的訊息數量與消費者處理的訊息數量之間的差異。監測消費者延遲可以幫助我們瞭解系統是否能夠跟上訊息的產生速度。

健康與不健康的延遲

圖 11-4 展示了不同情況下消費者延遲的變化。案例 a 和 b 表示健康的延遲,延遲最終會回到零。案例 c 和 d 表示不健康的延遲,延遲持續增加,可能導致訊息積壓和系統資源耗盡。

@startuml
skinparam backgroundColor #FEFEFE
skinparam monochrome false

title 串流資料管道中健康與不健康的消費者延遲模式

' 定義樣式
skinparam sequence {
    ArrowColor #333333
    LifeLineBorderColor #333333
    ParticipantBackgroundColor #E8F5E9
    ParticipantBorderColor #4CAF50
}

' 定義參與者
participant "生產者" as producer
participant "訊息代理\n(Message Broker)" as broker
participant "消費者" as consumer
database "延遲監控" as monitor

== 健康延遲模式 ==
note over producer,consumer #CCFFCC
  案例 a & b:延遲最終回到零
  特徵:訊息處理速度跟上生產速度
end note

producer -> broker : 發送訊息批次1
activate broker
broker -> consumer : 消費訊息
activate consumer
consumer -> monitor : 報告延遲:低
consumer --> broker : ACK確認
deactivate consumer
deactivate broker

producer -> broker : 發送訊息批次2
activate broker
broker -> consumer : 消費訊息
activate consumer
consumer -> monitor : 報告延遲:回歸零
consumer --> broker : ACK確認
deactivate consumer
deactivate broker

note over monitor #CCFFCC
  健康狀態指標:
  - 延遲趨勢向下
  - 最終回歸零
  - 系統資源可能過剩
end note

== 不健康延遲模式 ==
note over producer,consumer #FFCCCC
  案例 c & d:延遲持續增加
  風險:訊息積壓、資源耗盡
end note

loop 持續累積
    producer -> broker : 訊息生產速度 > 消費速度
    activate broker
    broker -> consumer : 處理緩慢
    activate consumer
    consumer -> monitor : 報告延遲:持續上升
    note right of monitor #FFCCCC
      警告:延遲增加
      原因可能:
      - 訊息量激增
      - 消費者效能下降
      - 資料處理複雜度提高
    end note
    consumer --> broker : 處理延遲
    deactivate consumer
    broker -> broker : 訊息堆積
    deactivate broker
end

note over monitor #FFCCCC
  不健康狀態指標:
  - 延遲持續增加
  - 訊息積壓嚴重
  - 需要立即干預
end note

== 解決方案 ==
note over consumer #E3F2FD
  處理延遲問題的策略:
  1. 增加消費者數量
  2. 最佳化消費者處理邏輯
  3. 調整訊息代理配置
  4. 過濾無關資料
  5. 診斷 Worker 效能問題
end note

@enduml

圖表翻譯: 此圖示展示了串流資料管道中健康與不健康的消費者延遲模式。在健康延遲模式(案例 a 和 b)中,生產者將訊息發送到訊息代理,消費者能夠及時處理訊息,延遲最終回歸零,顯示系統處理能力充足。而在不健康延遲模式(案例 c 和 d)中,訊息生產速度超過消費速度,導致延遲持續增加、訊息在代理中堆積,最終可能造成系統資源耗盡。圖表也列出了處理延遲問題的五大策略,包括增加消費者數量、最佳化處理邏輯、調整代理配置、過濾無關資料和診斷效能問題。透過監控這些延遲指標,團隊可以及時發現問題並採取相應措施,確保串流資料管道的健康運行。

如何處理延遲問題

  1. 增加消費者數量:如果延遲是由於消費者處理能力不足導致,可以考慮增加消費者數量以提高處理能力。
  2. 最佳化消費者處理邏輯:檢查消費者的處理邏輯,看看是否有最佳化的空間,例如提高處理效率或減少不必要的操作。
  3. 調整訊息代理組態:根據實際需求調整訊息代理的組態,例如增加緩衝區大小或調整訊息儲存策略。

資料管道監控與效能調優

在資料管道的運作中,監控是確保系統健康執行的關鍵。透過監控,我們可以及時發現問題並進行調整,以保持系統的最佳效能。

不健康的延遲(Unhealthy Lag)

不健康的延遲是指資料管道中訊息處理的延遲超過了預期。這可能是由於多種原因引起的,包括訊息量增加、資料量變化、worker 效能下降等。

訊息量增加

當訊息量突然增加時,資料管道可能無法及時處理,從而導致延遲。為瞭解決這個問題,可以透過擴充套件 worker 數量或增加 worker 的並發性來提高處理能力。

資料量變化

資料量的變化不一定意味著需要處理所有資料。在某些情況下,資料量的增加可能是由於新的資料特徵引起的,這些特徵可能與產品無關。在這種情況下,可以透過過濾掉無關資料來減少資料量,從而解決延遲問題。

Worker 效能下降

Worker 效能下降可能是由於多種原因引起的,包括資源競爭、外部資源限制等。為瞭解決這個問題,需要找出根本原因並進行相應的調整。

案例分析

在一個實際案例中,我們觀察到資料管道的延遲突然增加。經過調查,我們發現是由於資料函式庫資源競爭引起的。為瞭解決這個問題,我們重新思考了資料儲存策略,以最小化資料函式庫競爭。同時,我們也增加了 worker 數量和並發性,以充分利用資料函式庫資源。

健康的延遲(Healthy Lag)

健康的延遲是指資料管道中訊息處理的延遲在可接受的範圍內。當延遲很小且穩定時,可能意味著系統資源過剩,可以考慮減少 worker 資源以節省成本。

注意事項

在減少 worker 資源之前,需要考慮以下因素:

  • Broker 資源:減少 worker 可能會導致更多訊息堆積在 broker 上。
  • Consumer 可變性:是否可能出現 consumer 處理訊息時間變長的情況?
  • Producer 一致性:訊息是否來自穩定的資料來源?

Worker 利用率

Worker 利用率可以幫助我們瞭解系統資源的使用情況。透過比較 worker 設定和實際執行的任務數量,可以判斷是否充分利用了資源或是否存在資源浪費。

計算 Worker Slots

Worker slots = Worker 數量 × 每個 worker 的並發性

例如,如果有 2 個 worker,每個 worker 的並發性為 4,那麼最多可以同時執行 8 個任務。

案例分析

在一個實際案例中,我們透過監控 worker 利用率發現了資源浪費的問題。透過調整 worker 設定,我們成功地將資料攝入成本降低了一半。