從Debezium到Snowflake在生產中構建資料複製的經驗教訓 - Shippeo

banq發表於2022-07-17

Snowflake 和 Debezium 在現代資料堆疊中獲得了當之無愧的地位,現在很容易找到有關使用這些技術的線上資源。在這篇部落格中,我們更進一步,回顧了我們(在 Shippeo)使用 Debezium 近乎實時地將大規模資料複製到 Snowflake 中學到的經驗教訓。
資料是 Shippeo 業務的血液。作為供應鏈中的資料聚合器,新鮮可靠的資料對於提供準確的 ETA 預測和效能洞察至關重要。

這不是教程。我們不會解釋使用 Debezium 和 Kafka 將資料複製到 Snowflake 的不同步驟。線上可用的資源以及官方文件已經足夠了。我們想在這篇文章中與您分享的是蛋糕上的櫻桃;如果您想超越這些技術的簡單 PoC 到在生產中實際實施可靠系統,該做什麼和不該做什麼。

整體架構

從Debezium到Snowflake在生產中構建資料複製的經驗教訓 -  Shippeo
基於 KafkaConnect(Debezium)的資料複製管道概述

我們使用Debezium,一個優秀的開源工具來執行基於日誌的變更資料捕獲;這是使用 OLTP 資料庫的日誌來跟蹤和流式傳輸資料庫中的所有更改(作為事件)的過程。這些事件近乎實時地傳送到 Kafka,供多個 Kafka Sink 聯結器使用,並推送到下游的 OLAP 系統。
提前考慮最佳化Kafka使用

在開發週期開始時,您可以做出的決定很少會對您的 Kafka 使用產生巨大影響。例如,當在具有大型表的同一個 Kafka 叢集中使用多個 Debezium 聯結器時,給定的 Kafka 節點用盡磁碟空間或初始 Debezium 快照需要數天才能完成的情況並不少見。這裡有一些建議:

  • 使用正確的保留策略手動建立 Kafka 主題:如果 Kafka 主題不存在,Debezium 可以自動建立它們。最好避免這種情況。在初始化 Debezium 之前手動建立 Kafka 主題可以讓您控制每個主題的配置。例如,使用保留策略“Compact+Delete”對於 Debezium 使用的主題特別有用,因為它允許 Kafka 僅保留給定 Kafka Key 的最新訊息,從而減少儲存使用量。如果您有託管的 Kafka 服務,您可以使用指令碼或使用 Terraform 自動建立這些主題。這也將允許您根據相應表的大小微調每個主題的分割槽數(請參閱下一點)。
  • 增加最大表對應的 Kafka 主題的分割槽數量:這將增加 Kafka 中寫入操作的並行度,並大大加快大表的初始快照。
  • 將 AVRO 序列化與 Schema 登錄檔一起使用:而不是預設的 JSON 序列化。這將減少訊息大小並節省儲存使用量。這裡值得一提的是,一些 Kafka Sink 聯結器僅支援帶有 Schema 登錄檔的 AVRO,例如 BigQuery 接收器聯結器。所以最好提前準備。


為每個下游系統建立一個獨立的 Debezium 聯結器
假設您的資料科學家(使用 Snowflake 訓練模型)和資料分析師(使用 BigQuery 構建一些內部報告)都需要 MySQL 中的某些表。
由於將相同的源表複製到 2 個不同的目標,您可能想定義一個 Debezium 源聯結器,其資料由 2 個不同的 Sink 聯結器(在本例中為 Snowflake + BQ)使用。這會在資料消費者之間產生耦合,出於以下幾個原因,這是一個壞主意,包括:

  • 如果一個消費者需要重新初始化某個表的快照,另一個消費者也將被迫使用這個快照。
  • 如果一個消費者只需要某個大表的幾列,而另一個消費者需要所有列,那麼第一個消費者將被迫消費包含所有列的有效負載。

這打破了不同工作負載之間的隔離,使資料管道的維護變得複雜,併產生了不必要的計算成本。

小心在 PostgreSQL 中使用 Debezium
第一次在 PostgreSQL 上設定 Debezium 可能會很棘手。Debezium透過“出版物”和“複製槽”使用 PostgreSQL 的WAL (預寫日誌)。所有這些都需要正確配置才能使 Debezium 執行。雖然 Debezium 可以自動建立它們(如文件中所述),但它需要賦予 Debezium 的 DB 使用者對複製表的所有權特權。這不僅是一種反模式,而且從組織的角度來看甚至可能是不可能的,因為這些表很可能歸您公司的其他軟體開發團隊所有,而不是資料工程師。

更好的選擇是由表所有者或超級使用者手動建立這些複製槽。這篇文章很好地解釋了這一點。另一個關於 Debezium with PostgreSQL 是Ashhar Hasan的文章

對 WAL 大小失控的情況非常謹慎。這可能發生在此處解釋的高流量/低流量情況下,或者在一些手動測試後未使用複製槽。例如,如果您的 PostgreSQL 在啟用自動擴充套件的 GCP 的 Cloud SQL 上,那麼不斷增長的 WAL 將擴充套件資料庫的儲存(和成本),並且到目前為止,它不可能再次縮減。當您發現問題時,唯一的補救措施是刪除資料庫並重新建立它。

注意主要錯誤KAFKA-8713

從Debezium到Snowflake在生產中構建資料複製的經驗教訓 -  Shippeo
長話短說,如果有一個定義了預設值的可空資料庫列,那麼 KafkaConnect 會在序列化過程中錯誤地用預設值替換該列的任何空值。此錯誤會影響 Debezium 下游,因為它依賴於 KafkaConnect 序列化。
儘管此錯誤會損害此類列的資料完整性,但它似乎仍然沒有很快得到修復- 在撰寫本文時 -因為它需要 KIP (Kafka 改進提案)

對Snowflake 的思考
Snowflake 的好處在於它工作可靠。您需要擔心的事情並不多(除了您的信用使用賬單)。為了讓這個賬單不那麼痛苦,您可以最佳化 Snowflake Kafka 聯結器中的緩衝區配置,以便更明智地使用 Snowpipe。

從Debezium到Snowflake在生產中構建資料複製的經驗教訓 -  Shippeo
具有預設值的Snowflake Kafka接收器聯結器緩衝區配置

值得提出一個問題,即您需要多快將資料從 Kafka 中重新整理(從而觸發 Snowpipe)。每個資料管道都可以有不同的資料新鮮度要求。應該對緩衝區配置進行一些實驗,以找到成本和資料新鮮度之間的正確權衡。

Snowflake Kafka Sink 聯結器的一個不便之處在於它將資料推送到 Snowflake 半結構化(如 JSON),因此如果需要表模式,則需要對其進行轉換。在這個部落格中優雅地解釋了這一點。

關於監控的思考
Debezium 和 KafkaConnect 共同公開了一份詳盡的指標列表,這些指標可以為資料管道提供出色的可見性。但在所有這些指標中,有一個指標很突出:kafka_consumergroup_lag。
我不能強調這個單一指標可以告訴我們端到端資料複製管道的健康狀況。

從Debezium到Snowflake在生產中構建資料複製的經驗教訓 -  Shippeo
kafka_consumergroup_lag 的健康振盪趨勢

Kafka Exporter指標反映了消費者未消費的 Kafka 主題分割槽中排隊的訊息數。理想情況下,它應該在零和給定閾值之間波動(基於您的資料管道 SLA)。

  • 如果它停止上升: Debezium 已停止生成訊息。
  • 如果它停止下降:Snowflake已停止消費訊息。
  • 如果它太高:Snowflake消耗訊息的速度太慢。緩衝區重新整理配置應收緊。
  • 如果它不夠高: Snowflake 消耗訊息的速度太快。透過增加緩衝區重新整理限制可以節省 Snowpipe 成本。
  • 如果不存在: Kafka 可能不穩定。



 

相關文章