不知道這15個(gè)數(shù)據(jù)概念之前,你會(huì)覺得數(shù)據(jù)工程很難

凌晨兩點(diǎn),你很容易發(fā)現(xiàn)自己身處一條中斷的數(shù)據(jù)管道之中——日志默默地失效,指標(biāo)飆升,而且根本不知道哪里出了問題。你跟蹤作業(yè)、重試任務(wù)、刷新儀表板——直到你意識(shí)到:這不僅僅是管道或調(diào)度的問題。
數(shù)據(jù)工程不僅僅是管道,更是以數(shù)據(jù)為核心單元的系統(tǒng)設(shè)計(jì)。
在本文中,我將向您介紹15 個(gè)基本的數(shù)據(jù)工程概念。

在過去的幾年里,我見證了它們?cè)跇?gòu)建和擴(kuò)展大型系統(tǒng)時(shí)被反復(fù)使用。它們不僅僅是理論——它們是默默支撐著高彈性、可擴(kuò)展數(shù)據(jù)平臺(tái)的模式。
1. 批量與流式提取
a. 批量攝取會(huì)在一段時(shí)間內(nèi)(例如每小時(shí)、每天)收集數(shù)據(jù),并分塊處理。

例如:假設(shè)一家零售公司每天凌晨 2 點(diǎn)從其銷售點(diǎn)系統(tǒng)導(dǎo)出一次銷售交易數(shù)據(jù)。這些 CSV 文件會(huì)被上傳到 S3 存儲(chǔ)桶。Airflow 的每日 DAG 會(huì)提取這些文件,進(jìn)行處理,并將清理后的數(shù)據(jù)加載到 Snowflake 中。
適用于:大量、可預(yù)測(cè)的量
不適合實(shí)時(shí)需求或警報(bào)
b. 流式攝取在數(shù)據(jù)到達(dá)時(shí)以近乎實(shí)時(shí)的方式持續(xù)處理數(shù)據(jù)。

例如:一款拼車應(yīng)用會(huì)從司機(jī)端收集實(shí)時(shí)位置更新。這些數(shù)據(jù)會(huì)以事件的形式發(fā)送到 Kafka,由 Apache Flink 即時(shí)處理,并存儲(chǔ)在低延遲數(shù)據(jù)庫中,用于實(shí)時(shí)地圖和預(yù)計(jì)到達(dá)時(shí)間 (ETA) 的生成。
適用于:實(shí)時(shí)儀表板、異常檢測(cè)、警報(bào)
2.變更數(shù)據(jù)捕獲(CDC)
變更數(shù)據(jù)捕獲 (CDC) 是一種設(shè)計(jì)模式,它捕獲源級(jí)別的數(shù)據(jù)變化(插入、更新、刪除)并實(shí)時(shí)或近實(shí)時(shí)地傳播到下游系統(tǒng)。
CDC 允許您僅流式傳輸更改,而不是重新加載整個(gè)表,從而使管道更加高效、可擴(kuò)展和響應(yīng)。

例如:假設(shè)你在 Swiggy 或 Uber Eats 等外賣應(yīng)用上工作。該應(yīng)用將訂單信息存儲(chǔ)在 PostgreSQL 數(shù)據(jù)庫中:order_id、user_id、狀態(tài)(例如“已下單”、“已發(fā)貨”、“已送達(dá)”)、updated_at
問題:您的分析儀表板顯示每分鐘交付了多少個(gè)訂單,但它已經(jīng)過時(shí)了,因?yàn)楣艿烂扛魩讉€(gè)小時(shí)就會(huì)重新加載表格。
解決方案:您無需重新加載整個(gè)orders表,而是啟用CDC來僅在發(fā)生行級(jí)更改時(shí)進(jìn)行流式傳輸。

3.冪等性
在分布式數(shù)據(jù)系統(tǒng)中,事情會(huì)發(fā)生故障——而且故障方式往往是不可預(yù)測(cè)的。
這就是冪等性的由來。
冪等性是指你可以多次執(zhí)行相同的操作,而不會(huì)改變第一次執(zhí)行后的結(jié)果。換句話說,重復(fù)操作沒有副作用。
示例:無論用戶在 Instagram/Twitter 上點(diǎn)贊該帖子多少次,點(diǎn)贊數(shù)只會(huì)增加 1。

設(shè)計(jì)您的管道,使其能夠無憂地應(yīng)對(duì)故障和恢復(fù)。確保每個(gè)階段都具有重放安全性和無副作用。這種思維上的小轉(zhuǎn)變可以節(jié)省數(shù)小時(shí)的調(diào)試時(shí)間,恢復(fù)對(duì)數(shù)據(jù)的信任,并使您的管道達(dá)到生產(chǎn)級(jí)水平。
4.OLTP 與 OLAP
a. OLTP(聯(lián)機(jī)事務(wù)處理): OLTP 系統(tǒng)專為日常運(yùn)營而構(gòu)建。這些是您的應(yīng)用數(shù)據(jù)庫——快速、可靠,并針對(duì)實(shí)時(shí)讀寫進(jìn)行了優(yōu)化。
例如:在亞馬遜上下訂單、在帖子上發(fā)表評(píng)論。

處理/存儲(chǔ)平臺(tái):PostgreSQL、MySQL、DynamoDB、MongoDB
b. OLAP(聯(lián)機(jī)分析處理): OLAP 系統(tǒng)專為決策而非運(yùn)營而設(shè)計(jì)。它們旨在分析大量歷史數(shù)據(jù)、運(yùn)行復(fù)雜的聚合操作以及支持儀表板和業(yè)務(wù)報(bào)告。

平臺(tái):Snowflake、BigQuery、Redshift、Databricks SQL
我們從 OLTP 系統(tǒng)中提取數(shù)據(jù),進(jìn)行轉(zhuǎn)換和建模,然后加載到 OLAP 系統(tǒng)中。這是 ETL 和 ELT 背后的核心模式。
5.基于行的存儲(chǔ)與列式存儲(chǔ)
理解行式存儲(chǔ)和列式存儲(chǔ)之間的區(qū)別不僅僅是學(xué)術(shù)層面的問題——它直接影響查詢的運(yùn)行速度、存儲(chǔ)容量以及架構(gòu)的可擴(kuò)展性。這是一種低級(jí)設(shè)計(jì)決策,但會(huì)產(chǎn)生高層次的影響。
讓我們通過一個(gè)簡單的例子來探索這一點(diǎn),看看它將如何存儲(chǔ):

a. 基于行的存儲(chǔ):
在基于行的存儲(chǔ)中,數(shù)據(jù)一次存儲(chǔ)一整行——記錄的所有字段在物理上存儲(chǔ)在一起。
[1,“愛麗絲”,29,“美國”],[2,“鮑勃”,34,“加拿大”]
這意味著,如果您要讀取或更新完整記錄(例如用戶 #2),系統(tǒng)可以一次性檢索所有內(nèi)容。它針對(duì)需要頻繁插入、更新和讀取完整記錄的事務(wù)性工作負(fù)載進(jìn)行了優(yōu)化。
最適合:
- OLTP 系統(tǒng)(例如 MySQL、PostgreSQL)
- 快速插入/更新
- 記錄級(jí)訪問(例如,用戶資料、訂單)
b. 列式存儲(chǔ):
在列式存儲(chǔ)中,值按列存儲(chǔ),而不是按行存儲(chǔ)。給定列的所有值存儲(chǔ)在一起。
ID:[1, 2]姓名:[“Alice”, “Bob”]年齡:[29, 34]國家:[“USA”, “Canada”]
現(xiàn)在,如果您只想運(yùn)行如下查詢:
從用戶中選擇平均值(年齡);
列式存儲(chǔ)只會(huì)掃描指定列,跳過所有其他列。這使得對(duì)大型數(shù)據(jù)集的分析查詢Age速度極快。
最適合:
- OLAP 系統(tǒng)(例如 BigQuery、Snowflake、Redshift)
- 掃描、聚合、過濾
- 壓縮
6.分區(qū)
分區(qū)涉及將大型數(shù)據(jù)集劃分為更小、更合乎邏輯、更易于管理的部分/組,以加快查詢性能、減少資源使用并優(yōu)化數(shù)據(jù)存儲(chǔ)和檢索。
示例:您經(jīng)營一家比薩餅送貨服務(wù),并在名為的表中跟蹤所有訂單orders。

現(xiàn)在,如果您嘗試通過運(yùn)行一些 SQL 查詢來訪問數(shù)據(jù)。
沒有分區(qū):數(shù)據(jù)庫必須掃描每一行來找到匹配的日期。
SELECT * FROM訂單WHERE order_date = ' 2025-07-31 ' ;
使用分區(qū):假設(shè)我們已經(jīng)按 order_date 進(jìn)行了分區(qū)。

現(xiàn)在,如果您運(yùn)行上述相同的查詢,數(shù)據(jù)庫將僅讀取 2025-07-31 的文件夾。它會(huì)跳過其余部分。這使得查詢速度更快。

7. ETL 與 ELT
a. ETL(提取轉(zhuǎn)換加載):
這是一種傳統(tǒng)的數(shù)據(jù)管道方法,其中數(shù)據(jù)是:
從數(shù)據(jù)庫、API、平面文件或應(yīng)用程序等源系統(tǒng)中提取。
在到達(dá)目的地之前,在單獨(dú)的處理引擎中進(jìn)行轉(zhuǎn)換。此步驟可能包括清理、過濾、重復(fù)數(shù)據(jù)刪除和重塑數(shù)據(jù)。
加載到目標(biāo)系統(tǒng)(如數(shù)據(jù)倉庫或數(shù)據(jù)庫)進(jìn)行分析。

用例:
- 加載前需要保證數(shù)據(jù)的質(zhì)量和一致性。
- 您正在使用內(nèi)部部署系統(tǒng)或遺留基礎(chǔ)設(shè)施。
- 您想在存儲(chǔ)數(shù)據(jù)之前應(yīng)用復(fù)雜的邏輯或業(yè)務(wù)規(guī)則。
b. ELT(提取負(fù)載變換):
這是一種現(xiàn)代數(shù)據(jù)管道方法,其中:
提取的數(shù)據(jù)以原始形式立即加載到數(shù)據(jù)倉庫中。
轉(zhuǎn)換在倉庫內(nèi)部進(jìn)行,使用其內(nèi)置的處理能力(通常通過 SQL 或 dbt 等轉(zhuǎn)換工具)。

用例:
- 您正在使用基于云的數(shù)據(jù)倉庫(例如,Snowflake、BigQuery、Redshift)。
- 您想保留原始數(shù)據(jù)以供將來使用。
- 您需要快速攝取和靈活轉(zhuǎn)換。
8.CAP定理
CAP定理指出,任何分布式數(shù)據(jù)系統(tǒng)只能保證以下三個(gè)屬性中的兩個(gè):
一致性——每個(gè)用戶同時(shí)看到相同的數(shù)據(jù)
可用性——每個(gè)請(qǐng)求都會(huì)得到響應(yīng),即使它不是最新的數(shù)據(jù)
分區(qū)容忍度——即使網(wǎng)絡(luò)的某些部分出現(xiàn)故障,系統(tǒng)仍能繼續(xù)工作。

例如 :
- 對(duì)于訂單處理,您選擇CP(一致性 + 分區(qū)容忍度) ——拒絕訂單比造成重復(fù)更好——犧牲可用性。
- 對(duì)于餐廳搜索,您選擇AP(可用性 + 分區(qū)容錯(cuò)性) ——顯示稍微過時(shí)的結(jié)果是可以的——犧牲一致性。
9. 流式傳輸中的窗口
窗口化是根據(jù)時(shí)間或計(jì)數(shù)將無限數(shù)據(jù)流劃分為有限的、可管理的存儲(chǔ)桶(窗口)的過程,以便我們可以計(jì)算指標(biāo)、應(yīng)用聚合或觸發(fā)警報(bào)。
想象一下將一部永無止境的電影切成 5 分鐘的片段,一次分析一個(gè)場景。
Windows 類型:
a.滾動(dòng)窗口——固定大小、不重疊的時(shí)間間隔。
每個(gè)事件都只屬于一個(gè)窗口。
固定不重疊間隔。
示例:每1 分鐘統(tǒng)計(jì)一次用戶數(shù)
Windows:[12:00–12:01]、[12:01–12:02]、…
| — — — | — — — | — — — | W1 W2 W3
b.滑動(dòng)窗口
以較小間隔滑動(dòng)的固定大小窗口。
事件可能屬于多個(gè)窗口。
重疊窗口使分析更順暢
示例:使用 5 分鐘窗口每 1 分鐘計(jì)算一次滾動(dòng)平均值Windows:[12:00–12:05)、[12:01–12:06)……
| ------| | ------| | ------|
c.會(huì)話窗口
基于用戶活動(dòng)的動(dòng)態(tài)窗口,在一段時(shí)間不活動(dòng)后關(guān)閉。
用戶驅(qū)動(dòng)、基于活動(dòng)的窗口
示例:將用戶的點(diǎn)擊分組到間隔 < 30 秒的會(huì)話中。
用戶:點(diǎn)擊 — 點(diǎn)擊 — 等待 — 點(diǎn)擊 會(huì)話:|---| |---|
d.計(jì)數(shù)窗口
基于事件數(shù)量,而不是時(shí)間。
基于事件計(jì)數(shù)而不是時(shí)間。
示例:計(jì)算每 100 個(gè)事件的總和Windows:[1–100], [101–200], ...
使用事件時(shí)間+水印來處理遲到的數(shù)據(jù)。
工具: Apache flink、 Apache Beam、 Apache Spark Strcured Streaming、 Kafka Streams
10. DAG 和工作流編排
隨著數(shù)據(jù)系統(tǒng)日益復(fù)雜,協(xié)調(diào)運(yùn)行哪些程序、何時(shí)運(yùn)行以及以何種順序運(yùn)行已成為任何數(shù)據(jù)工程工作流程的關(guān)鍵部分。這正是DAG(有向無環(huán)圖)和工作流程編排的用武之地。
它們有助于確保您的管道順利運(yùn)行——就像指揮家指揮管弦樂隊(duì)一樣。
a.DAG(有向無環(huán)圖):
它是用于在編排工具中定義任務(wù)工作流的結(jié)構(gòu)。
定向:任務(wù)具有明確的順序(A→B→C)
非循環(huán):不允許循環(huán)或循環(huán)(您不能返回到上一個(gè)任務(wù))
圖:一組節(jié)點(diǎn)(任務(wù))和邊(依賴關(guān)系)
>>> 可以將其想象成一個(gè)流程圖,其中:
箭頭顯示執(zhí)行順序:

b. 工作流程編排:
工作流編排是定義、安排和監(jiān)控一系列任務(wù)(通常相互依賴)的過程,以自動(dòng)化數(shù)據(jù)管道、ML 訓(xùn)練、ETL 作業(yè)等。
簡單來說:這就是您如何協(xié)調(diào)不同的數(shù)據(jù)任務(wù),確保它們以正確的順序、正確的依賴關(guān)系運(yùn)行,并從故障中恢復(fù)。
工具: Airflow、 Prefect、 Dagster、 ADF 等。
11.重試和死信隊(duì)列
在數(shù)據(jù)工程中,失敗是不可避免的。網(wǎng)絡(luò)超時(shí)、記錄格式錯(cuò)誤、速率限制——最終都會(huì)出問題。
重要的是你如何處理它。
構(gòu)建彈性管道的兩個(gè)基本策略是:
重試邏輯——當(dāng)某些事情暫時(shí)失敗時(shí),請(qǐng)重試。
死信隊(duì)列 (DLQ) — 隔離并記錄不斷失敗的事件。
它們共同保證了管道的容錯(cuò)性、可觀察性和可恢復(fù)性。
a.什么是重試邏輯?
重試邏輯是一種策略:如果這個(gè)任務(wù)失敗了,讓我們?cè)诜艞壷霸僭囈淮巍?/span>

b.什么是死信隊(duì)列(DLQ)?
DLQ是一種特殊的隊(duì)列,您可以在其中發(fā)送反復(fù)無法處理的事件或消息 - 這樣它們就不會(huì)阻塞管道。
可以將其想象成壞數(shù)據(jù)的“隔離箱” 。
重試和 DLQ:傳入事件流 ↓ 驗(yàn)證架構(gòu) ↓ ┌──────────────┐ │ 豐富 API │ ← 超時(shí)重試└────┬────────┘ ↓ 錯(cuò)誤 事件 ?→是 → 發(fā)送到DLQ ↓ 保存到DWH

12. 回填和再處理
作為一名數(shù)據(jù)工程師,你的工作不僅僅是移動(dòng)數(shù)據(jù)——還要確保數(shù)據(jù)正確、完整、可信,即使出現(xiàn)問題。
這就是回填和再加工的作用所在。
這兩個(gè)概念有助于確保數(shù)據(jù)的完整性、準(zhǔn)確性和可信度——即使在出現(xiàn)故障、錯(cuò)誤或模式更改之后。
a. 何時(shí)重新處理?
轉(zhuǎn)換邏輯中的錯(cuò)誤(例如錯(cuò)誤的聚合公式)
新的業(yè)務(wù)規(guī)則需要不同的輸出
從一種格式轉(zhuǎn)換為另一種格式(例如,CSV → Parquet)
修復(fù)錯(cuò)誤的連接、錯(cuò)誤的查找、錯(cuò)誤的貨幣轉(zhuǎn)換
重新處理= 對(duì)處理不正確或邏輯/數(shù)據(jù)過時(shí)的日期重新進(jìn)行處理。
例子:
原始邏輯 (有缺陷): 銷售額 =數(shù)量 × 價(jià)格修復(fù)邏輯: 銷售額 = 數(shù)量 × 價(jià)格 × 貨幣兌換率→ 使用新公式重新處理舊數(shù)據(jù)
b.回填時(shí)?
管道中斷(例如,Airflow DAG 暫停 3 天)
數(shù)據(jù)源延遲上傳
遲到事件(在流媒體中很常見)
新添加的表或分區(qū)
需要納入的新邏輯。
例子:
由于上游 API 問題,7 月 15 日至 17 日的每日銷售作業(yè)失敗。修復(fù)后,您需要針對(duì)這些特定日期重新運(yùn)行管道以完成任務(wù)。
回填= 處理錯(cuò)過的過去日期的數(shù)據(jù)。

流程圖:
回填和重新處理。 ┌──────────────┐ │ 原始事件 │ ← 未處理的數(shù)據(jù)(例如,日志、用戶操作) └──────┬────────┘ │ ┌────────▼────────┐ │ 每日 ETL 作業(yè) │ ← 將原始事件轉(zhuǎn)換為干凈、可用數(shù)據(jù)的計(jì)劃作業(yè) └────────┬────────┘ ┌──────────────┴──────────────┐ │ 分區(qū)輸出 │ ←存儲(chǔ)在分區(qū)中的已處理數(shù)據(jù)(例如,按日期) └────────────┬──────────────┘ ▼ ┌────────────┐ ┌────────────┐ │ 回填15 │ │ 重新處理16 │ └────────────┘ └────────────┘
13.數(shù)據(jù)治理
數(shù)據(jù)治理是一組政策、流程、角色和工具,旨在確保整個(gè)組織的數(shù)據(jù):
原則 | 含義------------ | -------------------------------------可用 | 易于查找和訪問(安全)準(zhǔn)確 | 高質(zhì)量、值得信賴且經(jīng)過驗(yàn)證一致 | 跨團(tuán)隊(duì)定義和解釋相同安全 | 防止 未經(jīng)授權(quán)的訪問或?yàn)E用合規(guī) | 符合法律和監(jiān)管標(biāo)準(zhǔn)(例如 GDPR、HIPAA、SOX)
為什么它在系統(tǒng)設(shè)計(jì)中很重要?
信任與質(zhì)量:數(shù)據(jù)質(zhì)量差會(huì)導(dǎo)致洞察錯(cuò)誤,并削弱人們對(duì)數(shù)據(jù)產(chǎn)品的信任。治理需要強(qiáng)制執(zhí)行標(biāo)準(zhǔn),以保持一致性和準(zhǔn)確性。
安全和訪問控制:系統(tǒng)必須定義誰可以在什么條件下訪問哪些數(shù)據(jù),以及訪問的可見性。這需要在設(shè)計(jì)中集成身份驗(yàn)證、授權(quán)和加密。
法規(guī)合規(guī)性: 個(gè)人信息保護(hù)法、GDPR、HIPAA 和 CCPA 等法律要求對(duì)數(shù)據(jù)處理、沿襲、同意和保留進(jìn)行嚴(yán)格控制。不遵守規(guī)定可能會(huì)導(dǎo)致法律處罰和聲譽(yù)損害。
14. 時(shí)間旅行和數(shù)據(jù)版本控制
隨著數(shù)據(jù)量和復(fù)雜性的增長,了解過去任何時(shí)間點(diǎn)的數(shù)據(jù)狀況變得至關(guān)重要。無論您是在調(diào)試管道、審核數(shù)據(jù)合規(guī)性、基于歷史快照訓(xùn)練模型,還是在意外損壞后簡單地恢復(fù)數(shù)據(jù)集,時(shí)間旅行和數(shù)據(jù)版本控制都能提供可靠的工具來實(shí)現(xiàn)這些目標(biāo)。
時(shí)間旅行和版本控制賦予您的數(shù)據(jù)超能力。它們使您的管道可恢復(fù),您的模型可重現(xiàn),您的系統(tǒng)可審計(jì)。不要只是移動(dòng)數(shù)據(jù)——追蹤它、對(duì)其進(jìn)行版本控制,并尊重它的歷史記錄。
數(shù)據(jù)工程中的時(shí)間旅行是什么?
時(shí)間旅行功能允許您查詢特定時(shí)間點(diǎn)或特定版本的數(shù)據(jù)。您可以將其視為數(shù)據(jù)的“倒帶”按鈕:您可以回滾、比較歷史狀態(tài)或運(yùn)行時(shí)間點(diǎn)分析。
它本質(zhì)上是數(shù)據(jù)層的“undo”或“git checkout”版本。
例子:
SELECT * FROM sales_data VERSION AS OF '2025-07-01';——這將返回 2025 年 7 月 1 日表格的準(zhǔn)確內(nèi)容——即使此后已被更新或覆蓋。
什么是數(shù)據(jù)版本控制?
數(shù)據(jù)版本控制是對(duì)數(shù)據(jù)集隨時(shí)間變化的系統(tǒng)性跟蹤和管理。它包括在每次修改數(shù)據(jù)集時(shí)創(chuàng)建檢查點(diǎn)或提交——類似于使用 Git 對(duì)代碼進(jìn)行版本控制的方式。版本控制不僅適用于表或文件,還可能適用于模式、元數(shù)據(jù),甚至邏輯定義(例如,轉(zhuǎn)換步驟)。
在設(shè)計(jì)層面,版本控制可能發(fā)生:
- 行級(jí)(跟蹤記錄級(jí)更改)
- 在表級(jí)別(整個(gè)表快照)
- 在管道級(jí)別(版本化輸出或模型訓(xùn)練數(shù)據(jù))
例子:
在delta lake 中:-- 查看截至 7 天前的表SELECT * FROM events TIMESTAMP AS OF current_timestamp () - INTERVAL 7 DAYS; -- 查看特定版本的表SELECT * FROM events VERSION AS OF 42 ;在Apache Iceberg 中:SELECT * FROM sales.snapshots WHERE commit_at < '2024-12-01' ;
15.分布式處理概念
隨著數(shù)據(jù)集的增長超出單臺(tái)機(jī)器的容量,分布式處理成為數(shù)據(jù)工程的核心。它指的是將數(shù)據(jù)工作負(fù)載分解成更小的部分,并在集群中的多臺(tái)機(jī)器(節(jié)點(diǎn))上并行執(zhí)行。
核心原則:
a.數(shù)據(jù)分區(qū)。
分區(qū)意味著根據(jù)規(guī)則(例如日期、地區(qū)或客戶)將數(shù)據(jù)分成更小的塊。
假設(shè)您像這樣存儲(chǔ)銷售數(shù)據(jù):
分區(qū)前(1個(gè)大文件夾):
/銷售/所有數(shù)據(jù).csv
按月分區(qū)后:
/銷售額/月= 2025 - 06 / /銷售額/月= 2025 - 07 / /銷售額/月= 2025 - 08 /
現(xiàn)在,如果您想查找2025 年 8 月的銷售額,系統(tǒng)只會(huì)在一個(gè)文件夾中查找,而不是整個(gè)數(shù)據(jù)集。這使得您的查詢更快、更便宜。
分布式處理中的分區(qū)。
使用Apache Spark等工具時(shí),數(shù)據(jù)分區(qū)決定了計(jì)算的分布方式:
repartition(n):創(chuàng)建 n 個(gè)分區(qū)。
coalesce(n):無需完全改組即可減少分區(qū)。
partitionBy(col):保存數(shù)據(jù)時(shí),按列值拆分輸出。

b. 分桶。
讓我們通過一個(gè)例子來理解存儲(chǔ)桶。
假設(shè)你想快速找到一本書,但書都雜亂無章地堆在一起。逐一搜索每一本書會(huì)耗費(fèi)很長時(shí)間。于是,你根據(jù)書的類型將圖書館劃分成不同的區(qū)域(第 1 區(qū):小說,第 2 區(qū):懸疑,第 3 區(qū):歷史,等等)。
分類 — 根據(jù)作者姓氏對(duì)書籍進(jìn)行分類。
在每個(gè)部分中,書籍仍然太多,因此您可以通過分類來進(jìn)一步組織它們:
您可以根據(jù)作者姓氏的首字母將書籍放入標(biāo)有 A 到 Z 的書架上。
在每個(gè)部分中,姓氏以“A”開頭的所有作者都?xì)w入書架 A,“B”歸入書架 B,依此類推。
因此,分桶(Bucketing)會(huì)根據(jù)列的哈希值或值將每個(gè)分區(qū)內(nèi)的數(shù)據(jù)劃分成更小的“桶”(例如,按 customer_id 對(duì)銷售數(shù)據(jù)進(jìn)行分桶)。這有助于組織數(shù)據(jù),從而加快分區(qū)內(nèi)連接和查找的速度。

c. 數(shù)據(jù)傾斜
當(dāng)數(shù)據(jù)在處理過程中跨分區(qū)、存儲(chǔ)桶或節(jié)點(diǎn)分布不均勻時(shí),就會(huì)發(fā)生數(shù)據(jù)傾斜,導(dǎo)致某些分區(qū)的數(shù)據(jù)比其他分區(qū)多得多。
例子:
假設(shè)您有按 分區(qū)的銷售數(shù)據(jù)customer_id,并且您想按 將其與客戶數(shù)據(jù)連接起來customer_id。
客戶ID 銷售金額 1 100 1 50 1 30 2 20 3 200 1000 10000 1000 9000
如果 customer_id 1000 占銷售數(shù)據(jù)記錄的 90%,并且您的連接或聚合按桶進(jìn)行存儲(chǔ)customer_id,則 customer_id=1000 的桶會(huì)變得非常大 - 所有其他桶都很小。
這意味著處理存儲(chǔ)桶 1000 的處理節(jié)點(diǎn)已超載。
其他節(jié)點(diǎn)很快完成并等待空閑。
整個(gè)工作都被耽擱了。
處理數(shù)據(jù)偏度:
I. 加鹽(添加隨機(jī)前綴):
向傾斜鍵添加隨機(jī)前綴,以將數(shù)據(jù)分布在多個(gè)存儲(chǔ)桶中。
例子:
除了使用 之外customer_id=1000,還可以使用如下鍵:
1000_1
1000_2
1000_3
然后經(jīng)過加工,除去鹽分,重新聚合。
II. 廣播:
廣播是一種將小數(shù)據(jù)集復(fù)制(廣播)到分布式系統(tǒng)中的所有工作節(jié)點(diǎn)的技術(shù),以便每個(gè)節(jié)點(diǎn)都可以在本地訪問它,而無需重復(fù)地通過網(wǎng)絡(luò)發(fā)送數(shù)據(jù)。
from pyspark.sql.functions import broadcast # 廣播小數(shù)據(jù)框joined_df = large_df.join(broadcast(small_df), "id" ) --Spark 自動(dòng)將 small_df 廣播給所有執(zhí)行器。
III. 更改分區(qū)鍵
如果原始鍵嚴(yán)重傾斜,請(qǐng)使用不同的列進(jìn)行存儲(chǔ)/分區(qū)。
復(fù)合鍵(例如,customer_id + region)以實(shí)現(xiàn)更好的分布。
d. 洗牌。
混洗是在分布式系統(tǒng)中跨分區(qū)或節(jié)點(diǎn)重新分配數(shù)據(jù)的過程,通常是在需要根據(jù)鍵對(duì)數(shù)據(jù)進(jìn)行分組、連接或排序時(shí)。
假設(shè)房間里的每個(gè)人都拿著隨機(jī)的郵件。現(xiàn)在,你想按郵政編碼整理所有郵件,所以每張桌子都處理不同的郵政編碼。
每個(gè)人都必須在房間里走動(dòng)并將郵件投遞到正確的桌子上。
這就是改組——需要時(shí)間,而且成本高昂。
改組通常發(fā)生在這些操作中:
分組依據(jù)(例如,按地區(qū)劃分的總銷售額)
連接(特別是當(dāng)連接鍵位于不同的節(jié)點(diǎn)上時(shí))
排序/排序依據(jù)
按鍵/聚合減少
洗牌之前:工人 1: (A, 1 ), (B, 2 )工人 2: (A, 3 ), (C, 5 )洗牌之后 (groupBy key):工人 1:(A,1 ),(A,3 )工人 2:(B,2 )工人 3:(C ,5 )每個(gè)鍵現(xiàn)在都已本地化-但代價(jià)是數(shù)據(jù)移動(dòng)。 為了處理混洗,請(qǐng)使用廣播、預(yù)分區(qū)并避免廣泛的操作。
今天就到這里啦——希望對(duì)你有幫助!


























