Colocate Join :ClickHouse的一種高效能分散式join查詢模型

語言: CN / TW / HK
摘要:本文將介紹業界MPP分散式資料庫join查詢模型,以及ClickHouse的分散式查詢原理解析和Colocate join效能表現。

本文分享自華為雲社群《ClickHouse一種高效能分散式join查詢模型(Colocate Join)》,作者:tiantangniao 。

ClickHouse是一款開源的面向聯機分析處理的列式資料庫,具有極致的壓縮率和極速查詢效能。ClickHouse支援SQL查詢,基於大寬表的聚合分析查詢效能非常優異,在特定場景下ClickHouse也具備較優的join效能。本文將介紹業界MPP分散式資料庫join查詢模型,以及ClickHouse的分散式查詢原理解析和Colocate join效能表現。

1. ClickHouse分散式join

ClicHouse分散式join通常涉及到左右表為分散式表,分散式執行過程中需要將資料在節點間進行交換,我們將資料在節點間交換的動作在分散式執行計劃中稱為資料的流動streaming運算元,ClickHouse支援的streaming運算元有如下三種:

  • Broadcast Join
  • Shuffer Join
  • Colocate Join

以上第一種其實是資料廣播運算元,第二種為資料重分佈運算元,第三種為資料在本地不需要分散式交換。其實對於ClickHouse來說,說是實現了Shuffle JOIN比較勉強,其只實現了類Broadcast JOIN型別,ClickHouse的當前的分散式join查詢框架更多的還是實現了兩階段查詢按任務(這裡不詳細講解,後續幾個章節分別進行展開講解,大家可以體會),業界MPP資料庫分散式join查詢框架模型的資料在節點間交換Streaming運算元通常為以下幾種:

第一種Gather運算元類似於在ClickHouse中的SQL發起initiator節點,第一階段在各個節點完成本地join後,會將各節點結果傳送給initiator節點進行第二階段的彙總工作,initiator節點再講結果傳送給客戶端;第二種為資料廣播,單個節點將自己擁有的資料傳送給目標節點,對應到ClickHouse為Broadcast JOIN;第三種為資料重分佈,資料重分佈會將資料按照一定的重分佈規則傳送到對應的目標節點,對應到ClickHouse為Shuffer JOIN;最後一種資料會在本地進行join,對應到ClickHouse為Colocate join,其不需要資料重分佈或廣播,節點間和網路上無資料交換和傳播,此實現方式的join效能也最佳。以下分別將幾種join方式在ClickHouse中實現方式進行介紹。

1.1 Shuffer Join

1)有如下分散式Join SQL語句:

2)執行過程如下:

① 客戶端將SQL1傳送給叢集中一個節點host-0(initiator/coordinator);

② host-0節點將任務改寫為SQL2查詢任務;

③ Coordinator節點將SQL2查詢任務下發到叢集各個節點執行;

④ 各節點將SQL2解析為SQL3子查詢;

⑤ 子查詢被下發到所有節點執行;

⑥ 子查詢執行完成後將結果集返回到協調節點,如:host-j;

⑦ 協調節點將各個子結果集彙總為一個結果集;

⑧ 協調節點將結果集傳送到叢集各個節點,同時將SQL4任務下發到各個節點執行;

⑨ 各節點在本地將左表的分片和右表子查詢結果集進行join計算,然後將結果返回到客戶端。

3)總結:

  • ClickHouse 普通分散式JOIN查詢並未按JOIN KEY去Shuffle資料,而是每個節點全量拉取右表資料跟左表分片進行join計算;
  • 如果右表為分散式表,則叢集中每個節點會去執行分散式查詢,查詢會存在一個非常嚴重的讀放大現象。假設叢集有N個節點,右表查詢會在叢集中執行N*N次;
  • ClickHouse 的這種join方式和業界MPP的區別:雖然是叫做Shuffle join/redistribute join,但是從根本來說不是真正的redistribute join,存在查詢放大問題,也是效能較差的一種查詢方式。

1.2 Broadcast Join

1)有如下分散式Join SQL語句:

2)執行過程如下:

① 客戶端將SQL1傳送給叢集中一個節點host-0(initiator/coordinator);

② host-0節點將任務改寫為SQL2子查詢任務;

③ Coordinator節點將SQL2子查詢任務下發到叢集各個節點執行;

④ 各子節點任務執行完成之後將結果發回到協調節點;

⑤ 協調節點將上一步接收到的結果彙總為結果集;

⑥ 協調節點將結果集傳送到叢集各個節點,同時將SQL3任務下發到各個節點;

⑦ 各節點在本地將左表的分片和右表子查詢結果集進行join計算,然後將結果及發回到協調節點;

⑧ 協調節點將最終結果返回給客戶端。

3)總結:

  • 右表的查詢在initiator節點完成後,通過網路傳送到其他節點,避免其他節點重複計算,從而避免查詢放大問題;
  • GLOBAL JOIN 可以看做一個不完整的Broadcast JOIN實現。如果JOIN的右表資料量較大,就會佔用大量網路頻寬,導致查詢效能降低;
  • ClickHouse的global join方式和業界MPP的區別:
  1. ClickHouse會將右表過濾結果彙總到一個節點,然後又傳送到所有節點,對單節點記憶體/磁碟空間佔用較大,全量資料傳送到所有節點,對網路頻寬消耗也較大;
  2. 而業界MPP資料庫每個節點並行的將自己一部分資料廣播發到所有節點,之後就可以直接進行下一階段的本地join動作,多個節點都能並行執行,同時資料也不需要從一個節點發送到所有節點,對網路和單節點磁碟及記憶體消耗較少。

1.3 Colocate Join

1)有如下分散式Join SQL語句:

2)執行過程如下:

① 客戶端將SQL1傳送給叢集中一個節點host-0(initiator/coordinator);

② host-0節點將任務改寫為SQL2子查詢任務;

③ Coordinator節點將SQL2子查詢任務下發到叢集各個節點執行;

④ 各子節點任務執行完成之後將結果發回到協調節點;

⑤ 協調節點將上一步接收到的結果彙總為結果集返回給客戶端。

3)總結:

  • 由於資料已經進行了預分割槽/分佈,相同的JOIN KEY對應的資料一定儲存在同一個計算節點,join計算過程中不會進行跨節點的資料交換工作,所以無需對右表做分散式查詢,也能獲得正確結果,並且效能較優。

2. ClickHouse Colocate join

2.1 Colocate JOIN原理:

  • 根據“相同JOIN KEY必定相同分片”原理,我們將涉及JOIN計算的表,按JOIN KEY在叢集維度作分片。將分散式JOIN轉為節點的本地JOIN,極大減少了查詢放大問題。按如下操作:

1)將涉及JOIN的表字段按JOIN KEY用同樣分片演算法進行分片;

2)將JOIN SQL中右表換成相應的本地表名稱進行join。

2.2 Colocate JOIN效能:

  • 資料和用例準備

1)環境:準備2 shard,2副本共4個節點的ClickHouse計算節點叢集;

2)用例:分別建立join欄位按id % 2(2為shard個數,可根據實際叢集環境進行調整)取餘數據分佈方式(相同id資料分佈到同一個節點),以及RandRowbin (資料隨機rand分佈)資料分佈方式分散式表和本地表,分散式表指定分佈方式,本地表為Replicated表,具體用例如下:

  • colocate_join_a_local資料按照2分片(id % 2或雜湊取模)進行資料分佈;
  • 相同分佈列的欄位key的資料會分佈到同一個節點;
  • 資料通過分散式表colocate_join_a_dis把資料寫入分佈到各資料節點。

  • colocate_join_a_local_rand資料(rand())隨機分佈;
  • 相同分佈列的欄位key資料會隨機分佈到各節點;
  • 資料通過分散式表colocate_join_a_dis_rand寫入進行分佈。

  • 結果對比

2.3 Colocate Join場景約束

1)資料寫入

Colocate join場景需要使用者在系統建設前提前進行資料規劃,資料寫入時join的左右表join條件欄位需要使用相同雜湊演算法入庫分佈,保證join key相同資料寫入到同一個計算節點上。

  • 如果對資料寫入時效性要求不太高的場景,可通過分散式表進行生成資料,生成資料簡單快捷,效能較慢;
  • 如果對資料寫入時效性要求較高的場景,可通過應用/中介軟體寫入資料到local表,中介軟體需要實現入庫資料分佈演算法,入庫效能較好。

2)擴縮容

  • 擴縮容完成後,需要將全部資料重寫/重分佈一遍,缺點:耗時長,佔用儲存可能暫時會翻倍,一種節省空間的方式是:逐個表進行重分佈,每個表資料重分佈完成後可刪除重分佈前的資料,避免佔用過多儲存。將來的改進/增強:重分佈過程中支援可寫線上,重分佈儘量少或不影響寫入查詢的線上操作,減少重分佈過程中對客戶業務的影響。

3. 總結

業界所宣稱的ClickHouse只能做大寬表查詢,而通過以上分析,事實上在特定場景下ClickHouse也可以進行高效的join(Broadcast join和Colocate join)查詢,如果將表結構設計及資料分佈的足夠好,查詢效能也並不會太差:Broadcast join對於大小表關聯,需要將小表資料放在右邊;Colocate join需要將join key欄位使用相同的分佈演算法,將分佈鍵相同資料分佈在同一個計算節點。對於ClickHouse而言,當前優化器能力較弱,如join場景reorder以及統計資訊缺失,基於成本代價估算CBO的優化能力較弱,使用者SQL所寫即所得,可能會要求人人都是DBA,人人都要對ClickHouse或資料庫有深入的理解及經驗才能設計出較優的資料庫結構以及寫出較高效能的SQL語句。對於ClickHouse手動擋資料庫,將來我們也會在統計資訊、CBO優化器、分散式join模型框架、大大表等多表關聯查詢以及複雜查詢上進行優化增強,以降低使用者使用門檻,提升使用者使用體驗。

 

點選關注,第一時間瞭解華為雲新鮮技術~