引言
大家好,我叫張琦,來自每日互動,擔任大資料平臺架構師。今天我將分享我們團隊在基於Apache DolphinScheduler實現ClickHouse零壓入庫過程中的實踐經驗。
這個實踐專案涉及到兩個關鍵元件:Apache DolphinScheduler和ClickHouse,主要是我們在實際工作中遇到挑戰後的解決方案。透過調研開源元件、驗證官方建議和線上方法,我們最終找到了一種較為理想的實現方式,並將其落地。
分享內容概述
本次分享將主要分為以下三個部分:
- 面臨的技術挑戰
- 零壓入庫的實現方式
- 生產應用效果及思考
整個分享的內容設計較為簡潔,我們會圍繞實際遇到的問題和解決方案展開討論,並分享在開源和非開源技術中的探索和應用經驗。
最後,我們會講述生產應用中的效果,以便大家能夠從中獲得啟發,在未來的類似場景中取得更好的體驗和成果。
什麼是零壓入庫?
首先,我們先來解釋一下“零壓入庫”的概念。可能很多人聽過“零壓大床房”這個詞,它指的是讓人感受到舒緩、無壓力的睡眠體驗。
而在我們的技術場景中,“零壓入庫” 指的是如何讓 ClickHouse 在資料入庫時不產生明顯的系統壓力,從而保證服務的穩定性和高效能。
換句話說,我們希望透過最佳化讓 ClickHouse 在資料入庫時能做到“無感知”地處理這些操作,從而保證系統效能不受影響。這就是我們稱之為“零壓入庫”的原因。
面臨的挑戰
ClickHouse的優勢與劣勢
在實現ClickHouse的零壓入庫實踐中,我們首先需要深入瞭解其優勢和不足,以便於在實際應用中揚長避短。
ClickHouse的優勢和不足可以從以下幾方面來分析:
ClickHouse的優勢
高效能的儲存與查詢
ClickHouse的列式儲存結構讓其在資料壓縮和查詢速度方面表現優異。支援多種資料壓縮演算法(如LZ4和ZSTD),使用者可以根據伺服器配置選擇合適的壓縮演算法,在磁碟空間與CPU消耗之間進行平衡。在測試中,ClickHouse單機即可在毫秒級處理十億級別的資料,社群也在不斷更新,百億級資料下效能表現出色。
靈活的SQL支援
ClickHouse相容標準SQL,支援複雜查詢,包括視窗函式、自定義函式等,適用於大規模資料分析場景。其中對於bitmap的支援,非常優秀。
此外,ClickHouse還支援多源資料聯合查詢,能夠滿足多源跨表分析的需求。
單機百億級別效能
在64C CPU和256GB記憶體的配置下,ClickHouse單機可以輕鬆處理百億級別的資料,實現高效查詢和寫入。
ClickHouse的劣勢
硬體敏感性高
ClickHouse對硬體配置的要求較高,尤其對磁碟的效能非常敏感。不同於對CPU和記憶體的相對寬容,ClickHouse在機械硬碟和固態硬碟的使用體驗上有顯著差異,這也直接影響了資料的寫入效能。
寫入併發受限
ClickHouse的高查詢效能是以犧牲寫入效能為代價的,尤其在高併發寫入場景中易出現瓶頸。其推薦單機QPS/TPS不超過20,最好不超過100。高併發寫入會加重IO負擔,直接影響查詢和伺服器效能。
記憶體消耗高
ClickHouse在寫入資料和執行查詢時都對記憶體有較大需求,尤其是在執行關聯查詢時,需要大量的記憶體空間來快取和處理資料。對於記憶體配置不高的伺服器,寫入和查詢的記憶體需求可能會影響其他任務的正常執行。
合併效能低
ClickHouse的資料合併效能較差,資料入庫後可能需要花費數小時甚至更長時間進行檔案合併。檔案合併過程中會大量佔用IO、CPU和記憶體資源,影響整體效能。
海量資料入庫的挑戰
在海量資料入庫過程中,ClickHouse的弱點逐漸暴露,尤其是在日入庫量達到TB級別、數十TB級別甚至更高的情況下。
我們遇到的主要挑戰包括:
-
資料時效性受影響
在高併發寫入的場景中,伺服器的負載快速上升,寫入和查詢都會受到影響,導致資料時效性下降。
-
業務查詢的影響
在資料入庫期間,伺服器水位高企,業務查詢的效能會受到較大影響,甚至可能出現查詢失敗的情況。
-
叢集資源有限
如何平衡業務查詢和資料入庫的資源分配是一個重要的課題,特別是當叢集資源緊張時,往往難以保證兩者的效能。
-
資料堆積和補數問題
在資料量大、資料入庫效能受限的情況下,資料堆積和補數難度增加。資料堆積可能導致叢集效能下降,而補數時大批次寫入又容易引發效能瓶頸。
-
補數和依賴管理困難
在補數的過程中,批次部署和上下游依賴的處理較為複雜,入庫、告警等功能目前多依賴人工維護,缺乏自動化支援。
現有排程平臺的侷限性
之前,我們主要採用的是Azakaban排程平臺。它在早期大資料加工排程和日常資料運維中表現尚可,但在面向現代化的DataOps或Data AI場景下,表現出了一些不足。
例如,對於需要快速迭代的資料研發場景,Azakaban缺乏靈活性,且在自動化告警和維護方面較為薄弱,所以我們需重新選型一款排程產品來替代現有的技術棧。
總之,我們在ClickHouse零壓入庫實踐中,必須解決ClickHouse的硬體敏感性、寫入瓶頸和記憶體需求等方面的挑戰,同時探索新的排程平臺和方法來提升整體的執行效率。
零壓入庫的實現
為什麼選擇 DolphinScheduler
選擇 DolphinScheduler 作為排程引擎的主要原因包括以下幾點:
強大的排程能力
DolphinScheduler 已成為 Apache 頂級專案,具備了穩定的排程能力,支援複雜的任務流程管理,社群活躍度高,更新迅速。
這讓我們能夠高效實現各類複雜的資料排程需求,同時支援多種作業流程管理需求。
視覺化模板作業流
DolphinScheduler 的視覺化模板大大簡化了任務配置流程。資料開發人員可以透過模板快速建立作業流,支援直接在視覺化平臺上完成配置。
這樣,核心開發人員只需設計模板,其他使用者即可複用,大幅減少開發和配置時間。
豐富的重跑和補數機制
在 3.2.0 及後續版本中,DolphinScheduler 支援依賴資料節點的補數機制,即當上遊節點出現異常時可以一鍵啟動依賴鏈路中的所有節點自動補數。
此功能配合資料血緣圖使用,能有效降低資料維護難度,使資料問題排查和修復更加迅速。
多環境支援
DolphinScheduler 支援開發、測試、生產環境的無縫切換,允許使用者在開發環境完成除錯後將配置匯入測試環境,最終同步至生產環境,極大地提升了資料上線效率。
環境配置的靈活管理,使得多環境切換在保障資料安全的同時,還能加速資料任務的上線流程。
零壓入口平臺架構
我們的資料零壓入庫平臺架構分為幾層:
- 排程引擎與 BI 引擎:DolphinScheduler 為排程底層,引導 ClickHouse 和 Nebula 的 Worker 執行節點的操作,提供排程穩定性保障。
- 中心服務層:中心服務整合了 DolphinScheduler 的排程和資料管理功能,負責任務配置、日誌管理以及一鍵補數等關鍵功能。
- 資料質量模組:基於 DolphinScheduler 的監控功能,加入資料質量模組,用於監控資料入庫趨勢、鏈路檢查、大小與耗時分析等。告警模組提供多種告警方式,包括 HTTP、郵件、企業微信和釘釘等。
- 業務使用層:透過模板化開發,將 ClickHouse 和 Nebula 的入庫任務標準化,提升資料處理流程的易用性。公共工具如表合併工具、入庫檢查工具等進一步增強平臺的靈活性和實用性。
流程設計
零壓入庫的核心技術原則為“算力轉移”,即將 ClickHouse 入庫時的 CPU、記憶體和磁碟資源消耗盡可能轉移至大資料平臺 Yarn 中,從而減少對 ClickHouse 資源的佔用。
流程設計如下:
技術參考:
https://www.bilibili.com/read/cv16473965/
https://www.slidestalk.com/DolphinScheduler/SeaTunnelwithDolphinScheduler43829?embed
https://www.slidestalk.com/SeaTunnel/23020
https://seatunnel.incubator.apache.org/zh-CN/docs/2.3.3/connector-v2/sink/ClickhouseFile
https://clickhouse.com/docs/en/sql-reference/statements/attach
https://juejin.cn/post/7162441097514319909
https://clickhouse.com/docs/zh/operations/utilities/clickhouse-local
核心運算元的執行流程
在 Spark 中執行 ClickHouse 本地生成工具 ClickHouse Local,以預先生成符合 ClickHouse 分割槽要求的檔案。
執行步驟如下:
-
待入庫資料不需要排序
-
Spark在Driver中,連線ClickHouse獲取到表結構,按照表分割槽規則進行Spark sql重分割槽計算
-
Executor中
- 下載
ClickHouse-local
程式 - 讀取HDFS上重分割槽後的資料
- 載入使用者自定義函式
- 動態生成執行語句。執行命令生成表分割槽,包含索引、資料檔案等完整的分割槽目錄結構(基於配置化的引數,可以自行調整大小)
- 這兩個引數可以調整sql語句插入ck表時,
insert ck
表時,
單個最小切分分割槽目錄大小的引數
min_insert_block_size_rows=10000000,min_insert_block_size_bytes=1073741824
- 壓縮分割槽資料,上傳到HDFS
透過設計 Spark Executor 進行分割槽內資料處理,減少 ClickHouse 資源的消耗,並實現零壓入庫。與傳統 Insert Into 方法相比,這種方式降低了 ClickHouse 資源的佔用,同時提升了資料合併的效率。
總結來看,透過零壓入庫方案,我們實現了 ClickHouse 資料匯入的高效、低壓,並且大大減少了記憶體和 CPU 的消耗,確保資料入庫穩定高效,極大提升了 ClickHouse 在大資料場景下的資料處理效能。
生產應用效果
在我們的生產應用中,基於海豚的技術方案取得了一些顯著效果,具體包括以下幾個方面:
視覺化任務管理
- 開發人員可以建立任務模板,並將這些模板開放給其他資料研發人員使用。
- 目前主要透過複製或點選引用的方式進行使用。
支援重跑和失敗重跑
- 實現了任務的重跑和失敗重跑功能,利用社群現有的功能來降低人力和成本,提高資料研發效率。
監控告警
- 完善了監控告警機制,利用元件的豐富性建立了有效的告警機制。
資料質量檢查
- 入駐庫的資料質量檢查透過提供資料質量相關的運算元,若不夠用,使用者仍可自定義編寫Spark或SQL任務進行檢查。
記憶體監控與管理
- Worker監控機器伺服器資源,支援指令碼監控整個CK伺服器資源。
- 提供多環境支援及匯入匯出的釋出功能。
方案特點
我們的方案特點是“削峰不填谷”,透過提前完成CK檔案計算,僅在入庫時進行短時磁碟寫入,降低了CPU的負擔。
我們目前驗證的一些效果顯示,整體提升的效果基本上都在一倍或者一倍以上。具體而言,8小時的合併時間可以縮短至4小時,4小時縮短至2小時,2小時再縮短至1小時。
這些改進還可以根據不同使用者自行設定引數,系統提供了專案引數功能,可以直接引用全域性引數來使用,從而減少記憶體佔用並降低CPU使用率。
入庫過程最佳化
在入庫過程中,系統只需將資料從一個目錄搬到另一個目錄,就可以完成資料的入庫。得益於資料分塊更大,下載和解壓過程的CPU佔用率得以降低。
以下是最佳化的幾個關鍵點:
-
記憶體清理:記憶體的清理效果超出了我們的預期。在完成入庫時,系統會瞬時清理無效的快取和過期的記憶體標記檔案,整理記憶體,降低水位,為後續的查詢提供更多的記憶體空間。在生產環境中,這一記憶體清理操作經過多次驗證,對業務查詢沒有影響。
-
資料強一致性檢查:在使用
INSERT INTO
方式進行入庫時,如果資料在Spark或Flink任務中重複,而檢查機制不到位,則可能會造成資料問題。在我們的方案中,透過統計HDFS上的單個分割槽與生成的CK表的條數,一旦發現重複,系統會在合併時自動剔除重複資料,從而確保入庫資料的準確性。 -
資料時效提升:對入庫的資料進行統計檢查,發現重複資料問題,有助於及時解決業務和資料上的bug,計算、入庫、合併三個階段的耗時均有所下降,在資料入庫過程中,資源使用更高效,減少了CPU和記憶體的佔用。
我們的生產效果驗證了CK表的壓縮演算法及分割槽預生成的最佳化策略,實現了資源的高效利用和效能的顯著提升。這種方法不僅提升了入庫效率,還確保了資料質量與一致性,是我們未來應用的一個重要方向。
效能對比分析
常規方式 vs CK File 方式
以下是生產上使用單節點900GB大小資料的效能對比分析:
記憶體使用情況:使用 INSERT INTO
方式時,記憶體使用提升至80%(約200-220GB可用資源),但隨即出現記憶體回落現象。而使用CK File方式時,記憶體基本沒有上升,並且會釋放部分記憶體,最終穩定在50GB左右。
CPU佔用:在使用之前的JDBC方式時,CPU使用率明顯上升;而CK File方式的CPU上升幅度較小,整體減少了資源佔用。
IO效能:在JDBC與CK File的對比中,儘管峰值沒有太大差距(因磁碟使用率較高),但CK File的寫入速度更快,顯著減少了入庫所需時間。
儲存與壓縮演算法
整體效能提升還依賴於檔案大小的減少,採用CK表的壓縮演算法(預設LZ4)。我們建議設定為ZSTD以提高壓縮率,從而降低儲存壓力。不過,ZSTD對CPU的要求相對較高。
合併速度最佳化
透過控制預分割槽和生成的表分割槽塊大小,目前設定為每個分割槽1,000萬個資料,顯著減少了分割槽塊的數量,從而加快了合併速度,不消耗記憶體。
資源管理與擴充套件
在CK中,單個節點的資源是固定的(例如,64核、256GB記憶體)。若需擴容,只能進行橫向擴充套件。然而,將部分機器資源轉移至Yarn後,Yarn可以複用這些資源,使得CK的計算在Yarn上進行,從而有效提升計算效率。在理想情況下,可能將CK輸入庫的資料處理時間縮短至兩個小時。
資料處理收益分析
在資源管理方面,儘管我們在計算能力上有所提升,但實際使用的資源上升時間反而減少。這是因為機器的計算能力能夠更有效地均攤和利用,為其他業務線提供服務。
經過一段時間的驗證,我們的資料處理效果顯著提升,基本上都在一倍以上。
例如,原始檔案大小為 910 GB 的資料處理後,僅減少至 160 GB,實現了 82% 的壓縮。資料傳輸時間從 35 小時降至 1.5 小時,效率提升了 95%。
在入庫環節,耗時從 50 分鐘降至 20 分鐘,並且這一過程幾乎不消耗記憶體。合併時間更是從 6 小時縮短至 2 小時,極大地提升了資料處理的時效性。
Spark資源管理
透過最佳化資源配置,我們在 Spark 的資源使用上有所提升,雖然單個執行器的資源需求增大,但整體處理時長卻下降了近一半。
此外,在過去的一段時間裡,我們遇到了記憶體使用不均和入庫失敗的問題,但自從系統上線以來,這些問題得到了有效解決,資料處理過程也變得更加平穩。
- 資源要求:由於調大了1,000萬和1GB的資源要求,單個Executor的資源需求有所上升。
- 整體時長:處理時長下降接近一半。
記憶體管理與效能
記憶體的使用情況表現為時高時低,這主要是由於每次資料入庫後,系統會進行記憶體清理,有效降低記憶體水位,確保機器處於良好的狀態。
這種管理策略提高了系統的容錯性。在執行大型查詢任務時,我們能夠提前釋放記憶體,以滿足高記憶體需求的任務,從而為業務場景提供更多的應用可能。
- 在上線前,記憶體水位和OOM產生問題較為明顯,特別是在7月底的某個時間段內,常出現OOM入庫失敗和資料條數不一致的問題。
- 自7月24日至25號大規模投產後,資料和機器的壓力顯著下降,執行狀態趨於平穩。
這一功能確保了後續查詢能夠獲得更多的記憶體資源,進而提升了查詢效率。同時,我們的記憶體清理策略並沒有對業務查詢造成影響,這一策略的成功實施為後續的業務需求提供了強有力的支援。
以上是我們在資料處理中的一些收益和經驗分享,希望對你有幫助和啟發,歡迎大家提出疑問或進行交流與研究。
本文由 白鯨開源 提供釋出支援!