從 ClickHouse 到 ByteHouse:實時資料分析場景下的最佳化實踐

danny_2018發表於2023-02-01

作為國內規模最大的 ClickHouse 使用者,目前位元組跳動內部的 ClickHouse 節點總數超過 1.8W 個。綜合來說,位元組跳動廣泛的業務增長分析很多都建立在 ClickHouse 為基礎的查詢引擎上。

2021年8月,火山引擎基於位元組跳動內部最佳實踐,正式推出ByteHouse企業版,解決了開源技術上手難、試錯成本高等企業數字化轉型中遇到的技術痛點。

在打造ByteHouse的路程中,我們經過了多年的探索與沉澱,本文將分享位元組跳動過去使用 ClickHouse 的兩個典型應用與最佳化案例。

推薦系統實時指標

在位元組跳動內部“A/B 實驗”應用非常廣泛,特別是在驗證推薦演算法和功能最佳化的效果方面。最初,公司內部專門的 A/B 實驗平臺已經提供了 T+1 的離線實驗指標,而推薦系統需要更快地觀察演算法模型、或者某個功能的上線效果,因此需要一份能夠實時反饋的資料作為補充:

•能同時查詢聚合指標和明細資料;

•能支援多達幾百列的維度和指標,且場景靈活變化,會不斷增加;

•可以高效地按 ID 過濾資料;

•需要支援一些機器學習和統計相關的指標計算(比如 AUC)。

01 - 技術選型

位元組內部有很多分析引擎,ClickHouse、 Druid、 Elastic Search、 Kylin 等,透過分析使用者需求後選擇了 ClickHouse:

•能更快地觀察演算法模型,沒有預計算所導致的高資料時延;

•ClickHouse 既適合聚合查詢,配合跳數索引後,對於明細點查效能也不錯;

•位元組自研的 ClickHouse 支援 Map 型別,支援動態變更的維度和指標,更加符合需求;

•BitSet 的過濾 Bloom Filter 是比較好的解決方案,ClickHouse 原生就有 BF 的支援;

•位元組自研的 ClickHouse 引擎已經透過 UDF 實現了相關的能力,而且有比較好的擴充套件性。

每個產品都有自己合適的場景,但是對於當前場景的需求評估下,ClickHouse 更加合適。

方案對比

確認技術選型後,在如何實現部分,也有兩種方式:

最終方案及效果

由於外部寫入並不可控和技術棧上的原因,我們最終採用了 Kafka Engine 的方案,也就是 ClickHouse 內建消費者去消費 Kafka。整體的架構如圖:

•資料由推薦系統直接產生,寫入 Kafka——為了彌補缺少 Flink 的 ETL 能力,推薦系統做了相應配合,修改 Kafka Topic 的訊息格式直接適配 ClickHouse 表的 Schema;

•敏捷 BI 平臺也適配了一下實時的場景,可以支援互動式的查詢分析;

•如果實時資料有問題,也可以從 Hive 把資料匯入至 ClickHouse 中,除此之外,業務方還會將 1% 抽樣的離線資料匯入過來做一些簡單驗證,1% 抽樣的資料一般會儲存更久的時間。

除了技術選型和實現方案,我們在支援推薦系統的實時資料時遇到過不少問題,其中最大的問題隨著推薦系統產生的資料量越來越大,單個節點的消費能力也要求越來越大,主要碰到如下問題:

02- 挑戰與解決方案

問題一:寫入吞吐量不足

在有大量輔助跳數索引的場景下,索引的構建嚴重影響寫入吞吐量。

解決方案——非同步構建索引

社群版本的實現裡的具體邏輯如下:

•解析輸入資料生成記憶體中資料結構的 Block;

•然後切分 Block,並按照表的 schema 構建 columns 資料檔案;

•最後掃描根據 skip index schema 去構建 skip index 檔案。三個步驟完成之後才會算 Part 檔案構建完畢。

在需要保證構建完 columns 資料之後使用者即可正常查詢的前提下,ByteHouse 同步完成前面兩步,第三步把構建好的 Part 放入到一個非同步索引構建佇列中,由後臺執行緒構建索引檔案。

在改成非同步後,整體的寫入吞吐量大概能提升 20%。

問題二:Kafka 消費能力不足

社群版本的 Kafka 表,內部預設只會有一個消費者,這樣會比較浪費資源並且效能達不到效能要求。

嘗試最佳化過程:

•嘗試透過增大消費者的個數來增大消費能力,但社群的實現是由一個執行緒去管理多個的消費者,多個消費者消費到的資料最後僅能由一個輸出執行緒完成資料構建,所以這裡沒能完全利用上多執行緒和磁碟的潛力;

•嘗試透過建立多張 Kafka Table 和 Materialized View 寫入同一張表,但是對於運維會比較麻煩。

解決方案——支援多執行緒消費

前面提到的最佳化手段都不盡如人意,最後決定改造 Kafka Engine 在其內部支援多個消費執行緒,簡單來說就是每一個執行緒它持有一個消費者,然後每一個消費者負責各自的資料解析、資料寫入,這樣的話就相當於一張表內部同時執行多個的 INSERT Query。

透過多執行緒實現多消費者同時消費寫入表,寫入效能達到接近於線性的提升。

問題三:出現故障無法保證資料完整性

在主備模式下,如果資料同時兩個節點都寫入,一旦一個節點出現故障,新啟的節點恢復過程中容易出現各種問題,包括效能下降,無法保證分片,最嚴重可能導致查詢結果不正確。

解決方案——確保主備模式下只會寫入一個主備其中一個節點

為了避免兩個節點消費這個資料,改進版的 Kafka Engine 參考了 ReplicatedMergeTree 基於 ZooKeeper 的選主邏輯。對於每一對副本的一對消費者,會嘗試在 ZooKeeper 上完成選主邏輯,確保選舉成為主節點的消費者才能消費,另一個節點則會處於一個待機狀態。

有了這樣的單節點消費機制, 系統會檢測 ReplicatedMergeTree 表資料是否完整,如果資料不完整則代表不能正常服務,此時消費者會主動出讓 Leader,讓副本節點上成為消費者,也就是新寫入的資料並不會寫入到缺少資料的節點,對於查詢而言,由於查詢路由機制的原因也不會把 Query 路由到缺少資料的節點上,所以一直能查詢到最新的資料。

改進 Kafka Engine 確保主備模式下只有一個節點能消費資料,即使出現節點故障在新節點恢復過程中同樣保障瞭解決了資料完整性的問題。

廣告投放實時資料

第二個典型案例關於廣告的投放資料,一般是運營人員需要檢視廣告投放的實時效果。由於業務的特點,當天產生的資料往往會涉及到多天的資料。這套系統原來基於 Druid 實現的,Druid 在這個場景會有一些難點:

選擇了 ClickHouse 之後能解決 Druid 不足的地方,但還是有部分問題需要解決:

問題一:Buffer Engine 無法和 ReplicatedMergeTree 一起使用

社群提供了 Buffer Engine 為了解決單次寫入生成過多 Parts 的問題, 但是不太能配合 ReplicatedMergeTree 一起工作, 寫入不同 Replica 的 Buffer 僅快取了各自節點上新寫入的資料,導致查詢會出現不一致的情況。

解決方案改進了 Buffer Engine 做了如下的調整和最佳化:

•我們選擇將 Kafka/Buffer/MergeTree 三張表結合起來,提供的介面更加易用;

•把 Buffer 內建到 Kafka Engine 內部, 作為 Kafka Engine 的選項可以開啟/關閉,使用更方便;

•Buffer table 內部類似 pipeline 模式處理多個 Block;

•支援了 ReplicatedMergeTree 情況下的查詢。

首先確保一對副本僅有一個節點在消費,所以一對副本的兩個 Buffer 表,只有一個節點有資料。如果查詢傳送到了沒有消費的副本,會額外構建一個特殊的查詢邏輯,從另一個副本的 Buffer 表裡讀取資料。

增強 Buffer Engine,解決了Buffer Engine 和 ReplicatedMergeTree 同時使用下查詢一致性的問題。

問題二:出現當機後可能會出現資料丟失後者重複消費的情況

ClickHouse 缺少事務支援。一批次寫入只寫入部分 Part 後出現當機,因為沒有事務保障重啟後可能出現丟失或者重複消費的情況。

解決方案

參考了 Druid 的 KIS 方案自己管理 Kafka Offset,實現單批次消費/寫入的原子語義:實現上選擇將 Offset 和 Parts 資料繫結在一起,增強了消費的穩定性。每次消費時,會預設建立一個事務,由事務負責把 Part 資料和 Offset 一同寫入磁碟中,如果出現失敗,事務會一起回滾 Offset 和寫入的 Part 然後重新消費。

確保了每次插入資料的原子性,增強了資料消費的穩定性。

結語

實時資料分析是ClickHouse的優勢場景,結合位元組跳動實時資料場景的特點,我們對 ClickHouse 進行了最佳化和改造,並將這些能力沉澱到了 ByteHouse 上。ByteHouse 基於自研技術優勢和超大規模的使用經驗,為企業大資料團隊帶來新的選擇和支援,以應對複雜多變的業務需求,高速增長的資料場景。

未來,ByteHouse將不斷以位元組和外部最佳實踐輸出行業使用者,幫助企業更好地構建互動式大資料分析平臺。

來自 “ 過往記憶大資料 ”, 原文作者:ByteHouse;原文連結:https://mp.weixin.qq.com/s?__biz=MzA5MTc0NTMwNQ==&mid=2650740090&idx=1&sn=a04a1b,如有侵權,請聯絡管理員刪除。

相關文章