數據工程不只是寫管道:15 個系統設計核心思維
半夜兩點,報警短信響個不停,數據管道悄無聲息地掛了:日志卡住、指標亂飆、儀表盤延遲,老板在群里催進度,而你卻一頭霧水。追蹤任務、反復重試、刷新報表——直到那一刻才明白,這并不是單純的“調度問題”。
數據工程的本質,其實是以數據為核心的系統設計。
在這篇文章里,我想帶你梳理 15 個數據工程必懂的系統設計概念。它們幫助我把“救火式”開發,轉變為“可預期、可擴展”的平臺建設。這些概念看似抽象,卻是支撐現代數據系統的基石。
1. 批處理(Batch) vs 流處理(Streaming)
在數據工程里,數據如何被“采集和處理”,決定了整個系統的延遲、復雜度和適用場景。常見的兩種方式就是 批處理 和 流處理。
?? 批處理(Batch Ingestion)
批處理是把一段時間內產生的數據收集起來,集中處理。通常是 按小時、按天 等固定周期運行。
圖片
比如:一家零售公司每天凌晨 2 點從 POS 系統導出當天的銷售交易記錄(CSV 文件),上傳到 S3。接著,一個 Airflow DAG 會定時觸發,讀取這些文件,清洗后再寫入 Snowflake 數據倉庫。
適用場景:數據量大、結構穩定;報表分析、周期性統計;對實時性要求不高。
不適合:實時告警;秒級反饋。
?? 流處理(Streaming Ingestion)
流處理是另一種思路:數據一產生,就立刻被處理,幾乎實時流入系統。
圖片
比如:一家網約車公司采集司機的實時定位信息,這些事件會直接寫入 Kafka,由 Flink 等流式引擎即時消費,最后存入低延遲數據庫,用來支撐實時地圖和 ETA 預測。
適用場景:實時看板;異常檢測;實時告警與風控。
挑戰:架構復雜度更高;成本和運維要求更高。
2.變更數據捕獲(CDC)
變更數據捕獲(CDC)是一種設計模式,它能在數據源端實時(或近實時)捕獲數據的變更操作(增、刪、改),并將這些變更同步到下游系統中。
與整體重載整張表的方式不同,CDC 只同步發生變更的部分數據,從而使數據管道更高效、可擴展,并能快速響應變化。
圖片
舉個例子:假設你在一家類似 Swiggy 或 Uber Eats 的外賣平臺工作。訂單數據存儲在 PostgreSQL 數據庫中,包括訂單編號、用戶編號、狀態(如“已下單”“已派送”“已送達”)和更新時間。
問題:你的實時分析看板需要展示“每分鐘成功交付的訂單量”,但由于當前數據管道每隔幾小時才全量刷新一次,看板中的數據往往是滯后的。
解決方案:通過啟用 CDC,你無需重新加載整個訂單表,而是可以實時流式獲取每一條行級別的數據變更。這樣一來,數據看板就能實時反映最新訂單狀態,真正做到動態更新。
圖片
3.冪等性(Idempotency)
在分布式數據系統中,故障難以避免——而且往往以意想不到的方式發生。
這時就需要冪等性來保駕護航。所謂冪等性,是指同一個操作即便被重復執行多次,也不會產生超出第一次執行結果之外的影響。換句話說,重復操作不會帶來副作用。
舉個例子:無論在 Instagram 或 Twitter 上用戶重復點擊“點贊”多少次,最終的點贊數都只會增加 1。
圖片
因此,在設計數據管道時,要確保系統能夠在失敗和恢復中保持穩定。讓每一個處理階段都可安全重試、且無副作用。這一設計理念的微小轉變,不僅能節省大量調試時間、提升數據可信度,更能讓你的管道達到生產級可靠性。
4.OLTP 與 OLAP
a. OLTP(聯機事務處理)
OLTP 系統用于支持日常業務操作,例如應用程序的數據庫。它們通常具有高速、高可靠性,并針對實時讀寫進行優化。

示例:在亞馬遜下單購買商品、在社交平臺發布一條評論。 常用系統:PostgreSQL、MySQL、DynamoDB、MongoDB
b. OLAP(聯機分析處理)
OLAP 系統則專注于決策分析而非日常操作。它們擅長處理海量歷史數據、執行復雜聚合分析,并為看板和業務報表提供支持。
圖片
示例:分析銷售趨勢、統計用戶行為、生成財務報表。 常用平臺:Snowflake、BigQuery、Redshift、Databricks SQL
我們通常從 OLTP 系統中提取數據,經過轉換與建模,最終加載到 OLAP 系統中——這正是 ETL 和 ELT 背后最核心的數據流模式。
5.行式存儲 vs 列式存儲
理解行式存儲和列式存儲的區別,絕非紙上談兵——它直接影響到查詢速度、存儲效率,甚至整個架構的可擴展性。這是一個看似底層、卻牽動全局的關鍵設計選擇。
我們通過一個簡單示例來看它們的存儲方式:
圖片
a. 行式存儲(Row-Based Storage)
在行式存儲中,數據按行連續存放——即一條記錄的所有字段在物理上相鄰存儲。
[1, “Alice”, 29, “USA”], [2, “Bob”, 34, “Canada”]這意味著,如果你需要讀取或更新完整的一行記錄(比如用戶#2),系統可以一次性獲取所有字段。這種存儲方式適合事務型工作負載,常用于需要頻繁插入、更新和讀取整條記錄的場景。
IDs: [1, 2]
Names: [“Alice”, “Bob”]
Ages: [29, 34]
Countries: [“USA”, “Canada”]最適合:OLTP 系統(如 MySQL、PostgreSQL);頻繁插入/更新操作;記錄級訪問(如用戶檔案、訂單信息)。
b. 列式存儲(Columnar Storage)
列式存儲則按列組織數據——同一列的所有值連續存放在一起。此時,如果你只想執行如下查詢:
SELECTAVG(age)FROM users;系統只需掃描“年齡”這一列,跳過其他所有字段,從而大幅提升大數據集分析查詢的效率。
最適合:OLAP 系統(如 BigQuery、Snowflake、Redshift);大規模掃描、聚合和篩選;高壓縮存儲需求。
6.數據分區(Partitioning)
數據分區是指將大型數據集按一定規則拆分成更小、更易管理的邏輯塊,從而提升查詢性能、降低資源消耗,并優化數據的存儲和訪問效率。
舉例來說:假設你經營一家披薩外賣公司,所有訂單信息都存儲在 orders 表中。
圖片
當你嘗試運行如下 SQL 查詢某一天的訂單:
SELECT *
FROM orders
WHERE order_date = '2025-07-31';未做分區時:數據庫必須逐行掃描整個訂單表,才能篩選出符合日期條件的數據。
按 order_date 分區后:訂單表會按日期劃分為多個物理區塊(例如每天一個分區)。
圖片
此時再執行同一查詢,數據庫只會讀取 2025-07-31 對應的分區文件夾,自動跳過其他無關數據。查詢速度因此大幅提升。
適用場景:時間序列數據(如日志、訂單、事件流);需要頻繁按某一維度篩選(如日期、地區、類別);大型表查詢性能優化。
圖片
7.ETL vs ELT:兩種數據流程架構
在數據工程中,ETL 和 ELT 是兩種常見的數據處理流程架構,它們在數據提取、轉換和加載的順序及執行環境上存在顯著差異。
a. ETL(提取-轉換-加載)
ETL 是一種傳統的數據流程方法,其過程分為三步:
- 提取:從數據庫、API、文件或應用等源系統中抽取數據。
- 轉換:在數據到達目標系統之前,通過獨立的處理引擎進行清洗、過濾、去重、格式轉換等操作。
- 加載:將處理后的數據載入數據倉庫或數據庫,供分析使用。
圖片
適用場景:需要在加載前確保數據質量和一致性;基于本地或傳統基礎設施構建;需在存儲前。執行復雜的業務邏輯或規則
b. ELT(提取-加載-轉換)
ELT 是一種更現代的流程架構:
- 提取:從源系統獲取數據。
- 加載:直接將原始數據加載到數據倉庫中。
- 轉換:利用數據倉庫內置的計算能力(通常通過 SQL 或 dbt 等工具)在庫內進行轉換。
圖片
適用場景:使用云數據倉庫(如 Snowflake、BigQuery、Redshift);希望保留原始數據以備后續使用;需要快速數據接入和靈活的轉換能力。
8.CAP 定理
CAP 定理指出,任何分布式數據系統最多只能同時保證以下三個特性中的兩個:
- 一致性(Consistency):所有用戶在同一時刻讀取到的都是相同的數據
- 可用性(Availability):每一個請求都能獲得響應,即使返回的不是最新數據
- 分區容錯性(Partition Tolerance):即使部分網絡發生故障,系統仍能繼續運行
圖片
在實際應用中,我們需要根據業務場景做出權衡:
訂單處理系統通常選擇 CP(一致性 + 分區容錯性):寧可暫時拒絕訂單,也不能出現重復下單或數據錯亂——此時可以犧牲一定的可用性。
餐廳搜索功能則更適合 AP(可用性 + 分區容錯性):即使返回的結果略有延遲,也比完全無法提供服務要好——因此可以接受一定程度的數據不一致。
9.流處理中的窗口機制(Windowing)
窗口機制是一種將無界數據流按時間或數量劃分為有限數據塊(窗口)的方法,以便進行聚合計算、指標統計或觸發告警。
就像把一部永不結束的電影切成5分鐘的片段,逐段分析劇情。常見的窗口類型:
a. 滾動窗口(Tumbling Window)
- 固定大小、不重疊的時間區間
- 每個事件只屬于一個窗口
- 示例:每分鐘統計一次用戶數量
- 窗口示例:[12:00–12:01),[12:01–12:02)…
b. 滑動窗口(Sliding Window)
- 固定大小的窗口按更小間隔滑動
- 事件可能屬于多個窗口,窗口之間有重疊
示例:每1分鐘計算一次過去5分鐘的平均值
- 窗口示例:[12:00–12:05),[12:01–12:06)…
c. 會話窗口(Session Window)
- 基于用戶活動的動態窗口,一段時間無活動后自動關閉
- 示例:將用戶點擊行為分組,間隔超過30秒則開啟新會話
d. 計數窗口(Count Window)
- 基于事件數量(而非時間)劃分窗口
- 示例:每100個事件計算一次總和
- 窗口示例:[1–100],[101–200]…
處理延遲數據時,建議采用事件時間+水印機制,確保計算結果的準確性。
10.有向無環圖(DAG)與工作流編排
隨著數據系統日益復雜,如何協調任務執行的內容、時機與順序,已成為數據工程中的關鍵環節。此時,有向無環圖(DAG) 和工作流編排便發揮了核心作用。
它們就像樂隊的指揮,確保數據管道中的每個任務協調運作、有序執行。
a. 什么是有向無環圖(DAG)?
圖片
DAG 是工作流編排工具中用于定義任務流程的一種結構:
- 有向(Directed):任務之間有明確的執行順序(如 A → B → C)
- 無環(Acyclic):不允許出現循環或回退(不能從后任務跳回前任務)
- 圖(Graph):由節點(任務)和邊(依賴關系)組成
可以把它想象成一個流程圖:箭頭標明執行順序,任務按依賴關系依次觸發。
b. 什么是工作流編排?
工作流編排是指對一系列(通常相互依賴的)任務進行定義、調度和監控的過程,以實現數據管道、機器學習訓練、ETL任務等的自動化運行。
簡單來說:它是一種協調機制,確保多個數據任務能以正確的順序、依賴關系和容錯機制穩定執行。
11.重試機制與死信隊列
關鍵不在于杜絕問題,而在于如何妥善應對。
構建健壯數據管道的兩大核心策略是:
- 重試機制:在發生臨時性故障時自動重試
- 死信隊列(DLQ):隔離并記錄持續失敗的事件
二者結合使用,可顯著提升管道的容錯性、可觀測性和可恢復性。
a. 什么是重試機制?
重試機制是一種故障應對策略:當任務執行失敗時,系統不會立即放棄,而是自動嘗試重新執行。
典型重試場景包括:
- 網絡波動或瞬時超時
- 臨時性的服務不可用
- 資源短暫擁塞
b. 什么是死信隊列(DLQ)?
死信隊列是一個特殊的緩沖隊列,用于存放經過多次重試仍無法被正常處理的消息或事件,避免它們阻塞主流數據管道。
可以把 DLQ 看作一個“數據隔離區”,專門收納那些格式錯誤、無法處理或持續失敗的數據,便于后續排查與修復。
12.數據回填與重新處理
作為數據工程師,我們的職責不僅是搬運數據,更要確保數據正確、完整、可信——即使在出現問題之后。
這正是數據回填(Backfilling)和重新處理(Reprocessing)的意義所在。
它們幫助我們在發生故障、邏輯錯誤或 schema 變更后,依然保證數據的完整性、準確性和可靠性。
a. 什么時候需要重新處理(Reprocessing)?
重新處理是指對已處理過但存在錯誤或邏輯過時的數據,重新執行計算過程。常見場景包括:
- 轉換邏輯出現錯誤(如錯誤的聚合公式)
- 業務規則變更,需調整輸出結果
- 數據格式轉換(如 CSV → Parquet)
- 修復錯誤的關聯查詢、錯誤查詢或貨幣換算
示例:你發現訂單金額匯總邏輯有誤,需對過去7天的數據重新計算并更新結果。
b. 什么時候需要數據回填(Backfilling)?
回填是指對因故未能及時處理的某一時段歷史數據,進行補處理。常見場景包括:
- 數據管道故障(如 Airflow DAG 暫停運行3天)
- 數據源延遲上傳
- 流式數據中的延遲到達事件
- 新增表或分區
- 新邏輯需要覆蓋歷史數據
示例:由于上游API問題,7月15–17日的銷售任務執行失敗。修復后,需專門針對這三天重新運行管道,補全數據。
13.數據治理(Data Governance)
數據治理是一套集政策、流程、角色和工具于一體的管理體系,旨在確保企業中的數據達到以下目標:
- 可用可控:數據易于查找、訪問且使用規范
- 準確一致:數據可靠、統一,值得信賴
- 安全合規:數據受到保護,滿足隱私和監管要求
為什么在系統設計中至關重要?
- 信任與質量:低質量數據會導致錯誤洞察,削弱數據產品的可信度。數據治理通過執行標準保障數據一致性和準確性。
- 安全與權限管控:系統需明確定義不同角色在何種條件下可訪問哪些數據,并集成身份認證、權限管理及加密機制。
- 合規性要求:GDPR、HIPAA、CCPA 等法規對數據處理、血緣追蹤、用戶授權和數據留存提出嚴格要求。缺乏合規控制可能引發法律風險與聲譽損失。
14.數據時間旅行與版本控制
隨著數據量與復雜度的不斷提升,能夠追溯數據在任意歷史時刻的狀態變得愈發關鍵。無論是調試數據管道、合規審計、基于歷史快照訓練模型,還是意外數據損壞后的恢復,時間旅行與數據版本控制都為這些需求提供了可靠的技術基礎。
什么是數據時間旅行(Time Travel)?
時間旅行功能允許用戶查詢數據在歷史上某個特定時間點或特定版本的狀態。就像為數據提供了一個“回放按鈕”,你可以回退至某一時刻、比對不同時期的數據狀態,或執行時點分析。
通俗來說,就像數據層的“撤銷操作”或 git checkout,讓歷史數據狀態可查、可溯、可復用。
示例:某訂單表在周一誤刪了一批數據,借助時間旅行功能,可快速查詢周日23:59的數據狀態并進行恢復。
什么是數據版本控制(Data Versioning)?
數據版本控制是對數據集隨時間變更進行系統性跟蹤和管理的機制。它會在每次數據修改時創建檢查點或提交記錄——類似于用 Git 管理代碼版本。其管控范圍不僅包括表或文件,還可擴展至 schema、元數據甚至邏輯定義(如轉換規則)。
從設計層面看,版本控制可在以下層級實現:
- 行級版本控制:記錄行級別數據變更
- 表級版本控制:保存整張表的快照
- 管道級版本控制:對管道輸出結果或模型訓練數據進行版本化管理
示例:訓練機器學習模型時,可明確指定使用某版本的數據集,確保實驗可復現、結果可追溯。
15.分布式處理核心概念
當數據規模超出單機能力時,分布式處理成為數據工程的關鍵手段。其核心思想是將數據任務拆分為多個小塊,并通過集群中的多臺機器(節點)并行執行。包含一下幾個核心原理:
數據分區(Partitioning)
數據分區是指按照一定規則(如日期、地區、客戶等)將數據拆分為更小的邏輯塊
分桶(Bucketing)
以圖書館為例:首先按書籍類型分區(小說類、歷史類、科幻類…),但每個分區內書籍仍然很多。此時可進一步按作者姓氏首字母分桶(A-Z),將圖書歸到不同的書架上。
在數據工程中,分桶是指在每個分區內,按照列的哈希值或其他規則將數據劃分為更小的存儲單元(例如按 customer_id 分桶),可顯著提升分區內的關聯查詢和點查效率。
數據傾斜(Data Skew)
數據傾斜指數據在分區、分桶或節點間分布不均,導致部分任務負載遠高于其他任務。
示例:90% 的銷售數據集中來自 customer_id=1000 的客戶。在按 customer_id 進行關聯或聚合時,處理該客戶數據的節點將成為瓶頸,其他節點早早空閑,整體任務延遲。
應對數據傾斜的常見方法:
- 加鹽(Salting):為傾斜的鍵添加隨機前綴(如1000_1、1000_2),將數據分散到多個桶中,處理完成后再聚合結果
- 廣播(Broadcasting):將小數據集復制到所有工作節點,避免網絡傳輸和大表Shuffle
- 調整分區鍵:使用復合鍵(如 customer_id + region)或更換分布更均勻的列作為分區鍵
數據洗牌(Shuffling)
洗牌是指在分布式系統中根據鍵值重新分布數據的過程,通常發生在分組、關聯和排序等操作中。 類比:一個房間里每個人隨機拿著一些信件,現在需要按郵政編碼重新整理,大家必須走動并將信件放到對應郵編的桌子上——這個過程耗時且資源密集。
容易觸發洗牌的操作:Group By / 聚合;Join(尤其鍵值分布在不同節點時);Order By / 排序。
優化建議:盡量通過廣播、預分區等技術減少洗牌,避免寬依賴操作。
這15個系統設計概念,正是數據工程從“腳本小子”到“平臺架構”的關鍵分水嶺。它們不是孤立的術語,而是一套相互關聯、支撐現代數據系統的思維框架。























