博客 / 詳情

返回

浙江頭部城商行:每日 700 萬查詢、秒級響應,Apache Doris 查算分離架構破局資源衝突

在當前銀行業務全面線上化、實時化的驅動下,浙江省頭部城商行亟需構建一個能夠同時承載海量數據加工與高併發實時查詢的數據平台,以支撐精準營銷、實時風控和智能決策等關鍵業務。

在這一數字化轉型進程中,我們最終引入了 Apache Doris 作為湖倉一體架構的核心組件。Doris 憑藉其卓越的查詢性能、高吞吐、對標準 SQL 的完整支持以及高效的實時數據攝入能力,在多個候選方案中脱穎而出。尤其值得一提的是,其架構的靈活度及可擴展性、極大降低了運維難度和成本投入。截至目前,我們已順利完成 200TB+ 歷史數據的平滑遷移與落地,為後續的深度應用奠定了堅實基礎

1-整體架構圖.PNG

然而,在實踐過程中,“算”(批量數據處理)與“查”(業務實時查詢)這兩種負載在資源需求與業務目標上的根本性矛盾逐漸凸顯,解決這一矛盾已成為當下首要目標。

核心矛盾:“算”與“查”的資源爭搶

當“計算”和“查詢”共用一個 Doris 集羣時,資源爭搶問題十分突出。例如,批量計算任務會在短時間內會佔用大量 CPU、內存和 IO 資源,集羣負載驟升,直接影響同時運行的業務查詢的穩定性。其根本原因在於:

  • “算”的核心是吞吐量與任務交付。數倉專注於大規模數據的批量加工(如ETL、數據清洗與聚合計算),需要在有限資源下高效處理TB/PB級數據,確保任務在業務時間窗口內完成。其關鍵指標是任務成功率與產出時效,而對單個任務的響應時間並不敏感,只要能在業務允許的時間窗口內交付結果,即便耗時數小時亦可接受。
  • “查”的核心是響應速度與服務可用性。它直接面向一線業務端(如實時風控、客户畫像、經營報表),通常是對數倉加工後的結果數據進行即時查詢,對查詢響應速度和高可用有着嚴格要求——業務人員往往需要在秒級甚至毫秒級獲取查詢結果,且不能出現因集羣問題導致的查詢中斷,否則會直接影響業務正常運轉。

解決方案:查算分離架構設計

正因如此,我們意識到,要兼顧數據倉庫“計算”的效率與業務“查詢”的性能,“查算分離”架構是必然之選。該架構旨在將“計算”和“查詢”的負載拆分到不同的集羣中,使它們在各自專屬的資源環境下運行。這樣既能夠充分發揮數據倉庫的計算能力,又能確保業務查詢的響應時間和穩定性。

2-解決方案:查算分離架構設計.PNG

結合上圖所示的存算分離架構,我們通過以下四個方面的設計,系統性地實現了查算分離目標:

  1. 查詢低延遲保障
    為確保查詢的低延遲,在 Doris 中部署了獨立的查詢集羣,實現與計算集羣的物理資源隔離,從根本上避免批量任務對線上查詢的干擾。
  2. 數據實時同步
    為打通計算與查詢集羣之間的數據鏈路,引入跨集羣數據複製功能 CCR,實現表級數據的近實時同步。CCR 基於 Doris Binlog 的增量物理複製機制,可確保數據產出後快速同步至查詢集羣,且不影響線上查詢性能。基於該能力,已成功上線 500 張表、30TB 數據, 在跑批高峯期主從延遲也能控制在 15 分鐘內
  3. 高可用與容災
    我們構建了雙集羣熱備體系,日常將 95% 的查詢流量導向查詢集羣,5% 流量分流至計算集羣。通過持續的流量壓測,確保兩集羣隨時具備故障切換能力。
  4. 成本投入控制
    在保障查詢性能的前提下,為控制整體投入,我們在計算集羣中創建了與查詢集羣規格相近的 Workload Group(查詢 WG),並設置資源軟限制策略,允許 ETL 任務彈性複用其閒置資源。該設計在常態下顯著節約資源,儘管極端故障場景下全量切流可能引發短暫性能波動,但發生概率極低,風險整體可控。

優化實踐:性能提升百倍、 CPU 消耗僅 10%

查詢性能優化向來就是一個複雜的課題,它與 SQL 語句寫法、數據量的大小、建表的設計等多個因素共同影響,難以一蹴而就。在業務從原有系統遷移至新環境時, 我們暫未針對 Doris 進行優化,因此在業務上線初期遭遇性能挑戰:集羣 QPS 僅維持在 10 左右,而 CPU 消耗卻高達 90%。這樣的表現顯然無法滿足業務正常運轉的需求。

為此,我們從分區裁剪、記錄過濾、併發執行和查詢結果獲取這四個維度進行全面的優化。優化後,查詢性能相比之前提升百倍;在相同負載下,集羣 CPU 消耗從 90% 下降到 10% 內,效果十分顯著。在這次優化過程中,積累了不少實用經驗,在此分享給大家。

01 拆分查詢 SQL 、優化分區裁剪,查詢性能提升 6 倍

下方代碼塊展示了我們最常見的 SQL 模板,其典型特徵是根據 etl_job_flag 表中記錄的數據產出時間篩選最新的業務數據。由於分區字段 data_dt 的查詢條件是一個子查詢,導致 Doris 在執行時無法動態裁剪分區,只能掃描所有歷史分區,從而產生大量無效 IO。

我們對其進行了優化,首先將查詢 SQL 拆分成兩條 SQL 語句,先獲取數據產出時間,再查詢目標數據。其次將分區字段 data_dt 的條件調整為常量,限制其只掃描一個分區。通過該優化,實現了查詢性能 6 倍的提升

//  原始 SQL
select * from t where data_dt = (select max(data_dt) from etl_job_flag wehre etl_table ='t') and  其他過濾條件

//  優化後 SQL
select max(busi_dt) from etl_job_flag where  etl_table = 't'
select * from t  where data_dt  = xxx and 其他過濾條件

02 合理設計 Key 和索引,查詢性能提升 6-7 倍

Doris 的記錄過濾遵循“成本從低到高”的順序,依次為 Key Range 、索引過濾、 ZoneMap 和 BloomFilter 等輕量級過濾,最後執行謂詞評估。由此可知,合理設計 Key 和索引是提升篩選效率的關鍵。在實踐中,通過補充合適的 Key 和索引,查詢性能獲得 6-7 倍的提升

以用户信息表 user_info 為例:

  • 將高頻查詢字段 user_id設為 Unique Key 和分桶字段,以利用 Key Range 快速定位數據範圍。
  • 對次高頻查詢字段 user_name建立倒排索引,提高查詢效率。
  • 控制分桶大小在 1G~10G,減少 segment 文件數量,提升倒排索引查詢速度(Doris 每個 segment 文件對應獨立的倒排索引)。

03 參數調試, 查詢吞吐率提升 2-3 倍

高併發和低響應時間是查詢集羣的核心需求,適當調整 Doris 的執行相關參數可有效提升查詢吞吐量

  • parallel_pipeline_task_num:Pipeline task 是 Doris 執行調度的基本單元,parallel_pipeline_task_num 決定了單個查詢的最大併發度。該參數的默認值為 0,即 BE CPU 核心數的一半。
  • num_scanner_threads:Scan 算子負責數據掃描,為 Pipeline task 提供數據。num_scanner_threads 是單個 Scan 算子一次性提交到 Scan 線程池的任務數量,它直接影響查詢掃描數據的併發度。該參數默認值也為 0,動態計算。

如果將兩個參數的默認值設置為高值,可能導致單一查詢佔用過多資源,進而引發 CPU 緩存污染。根據實際應用經驗以及測試結果,建議可將 parallel_pipeline_task_num 設置為 8,將 num_scanner_threads 設置為 2,查詢吞吐率可提升 2 - 3 倍。此處作為參考,具體數值可根據實際業務情況來調整。

04 開啓行存、降低 IO 開銷,查詢性能提升 30%

在業務中,如果存在大量 SELECT * 的全列查詢,Doris 將默認採用按列存儲的方式,該方式需要讀取所有列並拼接成行返回。而對於字段較多的表,這並不是最佳處理方式,會導致極高的 IO 成本。

因此,我們在建表或修改表時配置 "store_row_column" = "true",開啓行存模式。避免了多列拼接的額外開銷,查詢性能提升約 30%

優化利器:慢查詢監測 + 性能壓測

01 報表 + Profile,全局觀測慢查詢

在性能優化中,慢查詢監測為我們提供了關鍵的數據洞察。通過對慢查詢的持續追蹤與分析,我們能夠快速定位根因、實施針對性優化,並最終驗證策略的有效性,確保我們的工作始終朝着正確的方向推進。

3-優化利器:慢查詢監測 + 性能壓測.png

作為監控集羣查詢狀態的核心入口,查詢報表在全局觀測中扮演着重要角色。它基於審計日誌(Audit log)及其他系統表構建,包括慢查詢榜單、響應時間統計和錯誤統計等信息。

Doris Profile 能夠詳細記錄查詢執行的統計信息,包括執行計劃、每個算子的耗時和數據掃描量等,為定位查詢性能問題提供了關鍵依據。Doris 默認的 Profile 存儲機制是保存在內存中,默認保留 500 個;而我們因業務需求,需對 3 天內歷史查詢問題進行保留,以便問題追溯。因此,我們基於 Doris Profile 開發了 Profile 歸檔服務

具體工作原理為:當查詢報表識別出慢查詢時,Profile 歸檔服務會自動從 Doris 集羣下載對應的 Profile 文件並保存至本地,同時生成專屬的 HTTP 鏈接。管理員在瀏覽慢查詢報表時,只需點擊鏈接,即可直接查看對應的完整 Profile,無需擔心因內存中 Profile 被清理而失去關鍵診斷信息,從而顯著提升歷史問題追溯的效率。

我們已在集羣全局啓用 Profile 功能,並將 auto_profile_threshold_ms 設置為 1000ms,這意味着所有執行時長超過 1 秒的查詢都會自動記錄 Profile,為後續分析提供充分的診斷依據。

查詢報表與 Profile 的聯動,構建了一套高效的性能優化閉環。一旦集羣出現異常,報表會通過內部 IM 自動告警,管理員隨即針對慢查詢榜單,藉助 Profile 進行深度分析、精準定位瓶頸。整個過程形成了從發現問題、精準定位到解決跟蹤的完整閉環。

02 查詢壓測工具,容量評估模擬器

此外,我們基於 Python 開發了查詢壓測工具,用於上線新業務、擴容集羣或優化配置之前,準確評估 Doris 集羣的承載能力。

其設計理念是還原真實負載:從 Doris Audit log 中提取歷史查詢記錄,通過多線程隨機回放的方式,模擬生產環境中的實際查詢壓力。在壓測過程中,工具會實時統計查詢吞吐量、響應時間分佈等關鍵指標。通過這些數據,我們能夠評估集羣的容量上限,或驗證優化措施的有效性,為集羣的資源規劃與架構調整提供重要依據。

結束語

通過以上優化,Doris 查詢集羣不僅實現了每日超 700 萬次查詢的穩定運行,99.95% 的查詢響應時間均在 1 秒以內,更在壓測中達到了 1500 QPS,充分驗證了其已具備支撐實時查詢的高性能與高穩定性,為 Doris 在湖倉一體平台中深度應用中掃清關鍵障礙。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.