Spark在什么情況下CBO才會判斷失誤,如何避免

在 Spark 中,CBO(基于成本的優化器,Cost-Based Optimizer)通過分析表的統計信息(如行數、列基數、數據分布等)計算不同執行計劃的“成本”,并選擇成本最低的計劃。但在以下場景中,CBO 可能因信息不足或計算偏差導致判斷失誤;針對這些場景,可通過主動干預避免問題。

一、CBO 容易判斷失誤的場景及原因

CBO 的核心依賴準確的統計信息對數據分布的正確建模,以下情況會破壞這兩個基礎,導致判斷失誤:

1. 統計信息缺失或過時

這是 CBO 失誤最常見的原因。

  • 缺失統計信息:Spark 不會自動收集所有表的統計信息(尤其是外部數據源如 CSV/JSON,或未執行過 ANALYZE 的表)。此時 CBO 只能基于“猜測”(如假設每個分區數據量相同、列基數為 1000 等)評估成本,必然導致偏差。
    例:一張實際有 1 億行的表,因未收集統計信息,CBO 誤認為只有 100 萬行,可能錯誤選擇“廣播連接”(本應走 Shuffle 連接),導致 Executor 內存溢出。
  • 統計信息過時:表數據發生大量增刪改后,統計信息未更新(如日均新增 1000 萬行的表,仍使用 1 個月前的統計信息)。CBO 基于舊數據評估成本,可能選擇低效計劃。
    例:一張表原本 100 萬行(CBO 選擇廣播連接),3 天后增長到 1 億行,但統計信息未更新,CBO 仍強制廣播,導致性能崩潰。

2. 數據分布極端(如傾斜或特殊分布)

CBO 假設數據分布是“均勻的”,但實際數據可能存在極端分布(如傾斜、長尾分布),導致統計信息(如平均基數)無法反映真實情況。

  • 數據傾斜:某列大部分值集中在少數 key 上(如 90% 數據的 user_id10086)。CBO 基于“平均基數”判斷該列數據量小,可能錯誤選擇廣播連接或 Shuffle 分區數,導致個別 Task 處理 90% 數據,出現 OOM 或長尾延遲。
  • 低基數列的特殊分布:例如列 gender 只有“男/女”兩個值(基數=2),但其中“男”占 99%、“女”占 1%。CBO 僅知道基數=2,可能高估過濾效率(如認為 where gender='女' 會過濾 50% 數據,實際過濾 99%),導致錯誤的連接順序。

3. 復雜查詢中的多表連接或子查詢

當查詢包含 3 張以上表的連接多層嵌套子查詢 時,CBO 需要評估的可能執行計劃數量呈指數級增長(如 n 張表連接有 n! 種順序)。此時 CBO 可能因“計算簡化”忽略最優解:

  • 例:4 張表 A(100 萬行)、B(10 萬行)、C(1 萬行)、D(1000 行)連接,最優順序應為 D→C→B→A(從小表開始連接,減少中間結果),但 CBO 可能因計算成本限制,隨機選擇 A→B→C→D,導致中間結果量激增。

4. 對 UDF 或特殊算子的成本估計偏差

CBO 對內置函數的成本(如 sumfilter)有成熟模型,但對 用戶自定義函數(UDF) 或特殊算子(如 windowdistinct)的成本估計可能失真:

  • UDF 無法被 CBO 解析內部邏輯,只能假設“固定成本”(如認為每個 UDF 調用耗時 1ms),但實際 UDF 可能是復雜計算(如正則匹配、JSON 解析),耗時遠超假設,導致 CBO 低估整體成本。
  • 例:一個耗時 100ms 的 UDF 被 CBO 誤認為 1ms,原本應避免在大表(1 億行)上執行該 UDF,但 CBO 認為成本低,最終導致查詢耗時超預期 100 倍。

5. 分區表的統計信息不完整

對于分區表(如按 day_id 分區的表),若僅收集全表統計信息而 未收集分區級統計信息,CBO 無法準確判斷“過濾特定分區后的數據量”:

  • 例:一張按 day_id 分區的表,全表 1000 個分區共 100 億行,但目標分區 day_id='2023-10-01' 實際只有 100 萬行。若未收集分區統計信息,CBO 會按全表平均(100 億/1000=1000 萬行)評估,可能錯誤選擇 Shuffle 連接(本可廣播)。

6. 外部數據源的元數據限制

對于非列式存儲的外部數據源(如 CSV、JSON、文本文件),或不支持元數據統計的數據源(如 HBase、JDBC 表),Spark 難以收集準確的統計信息(如行數、列基數):

  • 例:CSV 表無元數據,CBO 只能通過“采樣”估計行數(如采樣 1000 行推測全表),若采樣數據分布與真實分布偏差大(如采樣到的全是小值),會導致 CBO 對表大小的判斷錯誤。

二、避免 CBO 判斷失誤的核心措施

針對上述場景,可通過“保證統計信息質量”“主動干預優化器”“適配數據特性”三類方式避免失誤:

1. 確保統計信息準確且及時更新

統計信息是 CBO 的“眼睛”,需通過主動收集和更新保證其質量:

  • 定期執行 ANALYZE 命令

    • 全表統計:ANALYZE TABLE table_name COMPUTE STATISTICS(收集行數、大小等);
    • 列統計:ANALYZE TABLE table_name COMPUTE STATISTICS FOR COLUMNS col1, col2(收集列基數、分布等,對連接/過濾列至關重要);
    • 分區表:ANALYZE TABLE table_name PARTITION (day_id='2023-10-01') COMPUTE STATISTICS(單獨收集熱點分區的統計信息)。
    • 建議:在 ETL 流程結束后自動觸發 ANALYZE,或對高頻變更表設置每日定時更新。
  • 優先使用列式存儲格式:Parquet、ORC 等列式格式會自動存儲基礎統計信息(如每個列的 min/max/非空數),Spark 可直接讀取,減少手動 ANALYZE 依賴。

2. 主動干預優化器(使用 Hint 引導計劃)

當發現 CBO 選擇的計劃不合理時,可通過 Hint 強制指定執行策略(覆蓋 CBO 決策):

  • 連接策略:對小表強制廣播(/*+ BROADCAST(t) */),避免 CBO 因統計信息錯誤選擇 Shuffle 連接;對大表禁止廣播(/*+ NO_BROADCAST(t) */),避免 OOM。
    例:SELECT /*+ BROADCAST(b) */ a.* FROM a JOIN b ON a.id = b.id
  • 連接順序:通過 /*+ JOIN_ORDER(t1, t2, t3) */ 強制指定連接順序,適合多表連接場景(如已知 t3 是最小表,強制先連接 t3)。
  • Shuffle 分區數:通過 spark.sql.shuffle.partitions 調整(默認 200),避免 CBO 因低估數據量導致分區數不足(出現傾斜)或過多(資源浪費)。

3. 處理數據傾斜與極端分布

針對數據傾斜等 CBO 難以建模的場景,需手動優化數據分布:

  • 識別傾斜:通過 EXPLAIN 查看執行計劃中 Task 的數據量,或通過 Spark UI 的“Stage 詳情”觀察 Task 耗時分布(長尾 Task 通常對應傾斜)。
  • 解決傾斜
    • 對傾斜 key 拆分:將高頻 key 拆分為多個子 key(如 id=10086 拆分為 id=10086_1id=10086_2),分散到不同 Task;
    • 傾斜側廣播:若傾斜表是小表,強制廣播(避免 Shuffle 傾斜);若傾斜表是大表,對非傾斜 key 走 Shuffle 連接,傾斜 key 單獨處理。

4. 簡化復雜查詢與優化算子

減少 CBO 的計算壓力,降低其決策難度:

  • 拆分多表連接:將 4 表以上的連接拆分為多個子查詢(如先連接小表生成中間結果,再連接大表),減少 CBO 需要評估的計劃數量。
  • 替換 UDF 為內置函數:內置函數的成本模型更準確(如用 regexp_extract 替代自定義正則 UDF);若必須使用 UDF,盡量在小數據集上執行(如先過濾再 apply UDF)。
  • 避免不必要的 distinctwindow 算子:這些算子成本高,CBO 可能低估其開銷,可通過提前聚合或過濾減少數據量。

5. 升級 Spark 版本與監控執行計劃

  • 使用高版本 Spark:低版本(如 2.x)的 CBO 存在較多 bug(如對分區表統計信息處理錯誤),升級到 3.x 及以上版本可顯著提升 CBO 穩定性(3.x 對 CBO 進行了大量優化)。
  • 定期檢查執行計劃:對核心查詢使用 EXPLAIN COST 查看 CBO 計算的成本細節(如各計劃的行數、大小估計),對比實際運行數據,及時發現偏差并調整。

總結

CBO 判斷失誤的核心原因是“統計信息不可靠”或“數據特性超出建模能力”。通過定期更新統計信息用 Hint 干預關鍵計劃處理數據傾斜簡化復雜查詢,可大幅減少失誤概率。實際應用中,需結合 Spark UI 監控和執行計劃分析,持續優化統計信息和查詢邏輯,讓 CBO 更好地發揮作用。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/918167.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/918167.shtml
英文地址,請注明出處:http://en.pswp.cn/news/918167.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【第12話:感知算法基礎4】圖像分割:深度學習圖像分割模型介紹入門及常用模型詳解

深度學習圖像分割模型介紹入門及常用模型詳解 圖像分割是計算機視覺的核心任務,旨在將圖像劃分為語義區域。隨著深度學習的發展,分割模型在精度和效率上取得重大突破。以下按技術演進順序詳解主流模型:1. FCN(全卷積網絡&#xff…

AI 大模型企業級應用落地挑戰與解決方案

引言:AI 大模型的企業價值與落地困境近年來,以 GPT-4、Claude 3、文心一言為代表的大語言模型(LLM)展現出驚人的自然語言理解與生成能力,吸引了眾多企業的關注。據 Gartner 預測,到 2025 年,40%…

微服務如何保證系統高可用?

今天我們來探討一個綜合性但至關重要的話題:給你一個微服務應用,你該如何系統性地保證其高可用性?在互聯網技術崗的面試中,高并發、高可用和大數據通常被視為衡量候選人經驗的三大黃金標準。但說實話,是否擁有真正的高…

推理路徑的動態調控:讓大模型學會“恰到好處”的思考

當前大型語言模型(LLM)通過思維鏈(CoT)提升復雜任務推理能力,但研究表明其推理路徑存在嚴重冗余——例如反復驗證或無效思維跳躍,導致計算資源浪費和“幻覺”增加。論文:Test-time Prompt Inter…

springboot 2.4跨域變化和swagger結合的問題

前言 最近升級老項目,springboot2.2升級2.x最新版,升級項目本身升級很正常,畢竟springboot升級3.x以下,升級3.x需要spring6.x,需要jdk17.但是升級的項目在自測時正常,一旦真正測試就報跨域問題了。排查才發…

AWT 基本組件深入淺出:Button/Label/TextField/Checkbox/Choice/List 全面實戰與性能優化

Java AWT 基本組件的原理與用法,提供可運行示例、布局最佳實踐、事件處理與“性能優化”建議,幫助你快速構建穩定的桌面界面。 Java AWT, GUI, Button, Label, TextField, Checkbox, CheckboxGroup, Choice, List, 事件處理, 布局管理器, 性能優化 AWT…

邏輯回歸詳解:原理、應用與實踐

邏輯回歸詳解:原理、應用與實踐1. 邏輯回歸的基本原理1.1 線性回歸部分1.2 Sigmoid函數1.3 決策邊界2. 邏輯回歸的損失函數3. 邏輯回歸的應用場景4. 邏輯回歸的優缺點4.1 優點4.2 缺點5. 使用scikit-learn實現邏輯回歸6. 邏輯回歸的改進與擴展6.1 正則化6.2 多分類擴…

嵌入式硬件接口總結

嵌入式系統的核心在于其硬件與軟件的無縫協作,而硬件接口是實現這種協作的物理和邏輯橋梁。它們定義了微控制器、處理器、傳感器、執行器、存儲器以及其他外設之間如何交換數據、電信號和控制信息。 核心概念 接口的定義: 兩個獨立系統或組件之間進行通信…

《算法導論》第 14 章 - 數據結構的擴張

大家好!今天我們來深入學習《算法導論》第 14 章 —— 數據結構的擴張。這一章主要介紹了如何基于現有數據結構(如二叉搜索樹)擴展出新的功能,以滿足更復雜的問題需求。我們會從動態順序統計樹講到區間樹,每個知識點都…

Vue 3.6 Vapor模式完全指南:告別虛擬DOM,性能飛躍式提升

什么是 Vapor 定義: Vue 3.6 新增的編譯/渲染模式,不再構建/對比虛擬 DOM,而是將模板編譯為“直達 DOM 的更新代碼”,以更低內存與更快更新獲得接近 Solid/Svelte 的性能。特點更快: 跳過 VDOM 創建與 diff,直接按依賴精準更新。…

Java類和對象課上練習題目設計

我們可以做一個簡易銀行賬戶類,支持存款、取款、查看交易記錄等。 示例:BankAccount 類 java 復制 編輯 public class BankAccount { private String accountNumber; // 賬號 private String ownerName; // 開戶人姓名 private double balance; …

Python數據雙效處理:同步轉換與換算的高級技術與工程實踐

引言:轉換與換算在現代數據處理中的核心價值在大數據與實時處理需求激增的時代,高效的數據處理方案成為核心競爭力。根據2025年Python數據工程調查報告:75%的數據處理任務需要同時執行轉換和換算操作優化良好的雙效處理可提升3-8倍性能關鍵應…

Go語言實戰案例:文件上傳服務

在 Web 開發中,文件上傳 是常見需求,例如頭像上傳、文檔存儲、圖片分享等功能。Go 語言的標準庫 net/http 已經內置了對 multipart/form-data 類型的支持,能讓我們輕松構建一個文件上傳服務。本文將帶你實現一個可運行的文件上傳接口&#xf…

【Lua】常用的庫

os庫:os.time() -- 輸出當前時間的時間戳 os.time({year 2014, month 8, day 14}) -- 獲取指定時間的時間戳local nowTime os.date("*t") -- 以表的形式獲取當前的時間信息for k,v in pairs(nowTime) doprint(k,v) end--以上for循環示例輸出 {year 2…

Mac上安裝和配置MySQL(使用Homebrew安裝MySQL 8.0)

在Mac上安裝MySQL是一個簡單高效的過程,尤其是通過Homebrew這一強大的包管理工具。本文將詳細介紹如何在macOS 15.6系統中使用Homebrew安裝MySQL 8.0版本,并完成基本配置,幫助您快速啟動并安全使用MySQL。1. 安裝Homebrew(若未安裝…

【Datawhale AI夏令營】從Baseline到SOTA:深度剖析金融問答RAG管道優化之路

從Baseline到SOTA:深度剖析金融問答RAG管道優化之路 引言 檢索增強生成(Retrieval-Augmented Generation, RAG)已成為構建知識密集型AI應用的事實標準 1。然而,從一個簡單的“hello world”級別的RAG,進化到一個能在競…

AI鑒偽技術:守護數字時代的真實性防線

文章目錄一、引言:AI偽造技術的“數字病毒”與鑒偽技術的“免疫疫苗”二、合合信息三大AI鑒偽技術解析2.1 人臉視頻鑒偽技術:毫秒級擊穿“數字假面”2.1.1 技術突破:從“像素級標記”到“多模態交叉驗證”2.2 AIGC圖像鑒別技術:讓…

論文reading學習記錄7 - daily - ViP3D

文章目錄前言一、題目和摘要二、引言三、相關工作四、方法五、訓練前言 開沖,清華大學的,帶HDmap的端論文,用的Query,和UniAD一樣。 一、題目和摘要 ViP3D: End-to-end Visual Trajectory Prediction via 3D Agent Queries ViP3…

Java學習第一百零九部分——Jenkins(一)

目錄 一、前言簡介 二、核心價值與優勢 三、關鍵概念 四、下載安裝與配置 五、總結歸納概述 一、前言簡介 Jenkins 是一個開源的、基于 Java 的自動化服務器。它的核心使命是實現持續集成和持續交付。簡單來說,Jenkins 是一個強大的工具,用于自動化…

微算法科技(NASDAQ:MLGO)使用循環QSC和QKD的量子區塊鏈架構,提高交易安全性和透明度

隨著量子計算技術的快速發展,傳統區塊鏈所依賴的加密算法面臨著被破解的潛在風險。量子計算的強大計算能力可能會在未來打破現有加密體系的安全性,從而對區塊鏈中的交易數據造成威脅。為了應對這一挑戰,將量子技術與區塊鏈相結合成為了必然的…