4個優化方法,讓你能瞭解join計算過程更透徹

華為雲開發者社群發表於2021-12-13
摘要:現如今, 跨源計算的場景越來越多, 資料計算不再單純侷限於單方,而可能來自不同的資料合作方進行聯合計算。

本文分享自華為雲社群《如何高可靠、高效能地優化join計算過程?4個優化讓你掌握其中的精髓》,作者: breakDraw 。

現如今, 跨源計算的場景越來越多, 資料計算不再單純侷限於單方,而可能來自不同的資料合作方進行聯合計算。

聯合計算時,最關鍵的就是標識對齊,即需要將兩方的角色將同一個標識(例如身份證、註冊號等)用join操作關聯起來, 提取出兩邊的交集部分, 後面再進行計算,得到需要的結果。

而這種join過程看似簡單,其實有非常多的門道,這裡讓我從最簡單的join方法開始, 一步步演示join的優化過程。

首先假設以下場景:

  • 有tb1, tb2兩張表的資料,存放在不同位置
  • 各有相同的id列。
  • tb1有1億行資料,而tb2表只有10w行資料。

1.簡單全集2次迴圈碰撞

拿到2張表的全量資料, 直接2個for迴圈進行遍歷

如果id匹配,則合併2個行記錄作為join結果

for (row r1 : tb1) {
    for(row r2 : tb2) {
        if(idMatch(r1, r2) {
            // 獲取r1和r2拼接後的r3
            r3 = join(r1,r2)
            result.add(r3)        
        }
    }
}

圖示如下:

4個優化方法,讓你能瞭解join計算過程更透徹

上面這種join有2個問題:

  1. 效能很差,兩次for迴圈相當於O(mn)的複雜度
  2. 為了收集全量資料, 可能導致記憶體溢位,例如大表有10億行資料,無法一次性存放。

2. 使用雜湊表優化效能

首先解決剛才提到的第一個問題

實際上join過程就很像一種命中過程, 因此可以聯想到雜湊表。

  1. 我們使用一個 hashMap儲存較小的tb2表(只有10w行)。
    使用id列當作雜湊表的key。
  2. 只對大表做for迴圈,如果id列在雜湊表中能匹配中,則取出對用資料做拼接
for (row r1 : tb1) {
    if(idMap.containKey(r1.getId())) {
        row r2 = idMap.get(r1.getId());
        r3 = join(r1,r2)
        result.add(r3)        
    }
}

這樣複雜度就優化到了O(m)了

3. 大表資料分批傳輸

還有一個問題沒解決: ”為了收集全量資料, 可能導致記憶體溢位“。

那我們可以將大表按照特定數量進行拆分,分成多批資料

例如每次以1000條的數量,和小表進行上面的雜湊表碰撞過程。這樣空間複雜度就是O (K + n)。

當每碰撞完一次,才接著接收下一批資料。如下面所示

4個優化方法,讓你能瞭解join計算過程更透徹

注意, ”告知計算完成這種響應機制“也可以優化成阻塞的緩衝佇列。

但是還有個問題, 如果小表本身也很大, 例如1億條, 計算節點連小表的雜湊表都存不下,怎麼辦?

另外單節點計算的CPU有限,如何能在短時間內快速提升效能?

4. 分散式計算

當計算節點存不下小表構成的雜湊表時, 這時候可以擴容2個join計算節點, 引入分散式計算來分擔記憶體壓力。

例如我們可以對id列進行shuffle分片

  • id%3==0 分到計算節點A
  • id%3==1 分到計算節點B
  • id%3 ==2 分到計算階段C

如果id是均勻的, 則小表的資料就被拆成了3份,也許就能正好存下了。

大表資料按同樣的方式分片, 分到相同的節點, 對計算結果是沒有影響的, 只要你的分片演算法確保id匹配的行一定在同一個節點即可。

4個優化方法,讓你能瞭解join計算過程更透徹

另外效能上, 分散式計算理論上按照節點數量也能夠提升N倍的join速度。

這種分散式計算的方式已經能解決大部分join作業了,但是還有個問題:

  1. 假設網路頻寬壓力比較大(比如買的頻寬比較便宜,傳送資料的成本比較大)
  2. 部分涉及安全的計算場景中可能需要對資料做加密
    這2種情況都會造成資料在輸出時會耗費很多時間,甚至超過join的過程。那麼該如何優化?

5. 本地join計算

本地計算,指的就是在通過網路輸出資料前,先提前做一些預處理。這種操作在各種計算引擎中都有體現

  • 在spark中有一個叫boardCast廣播資料的機制
  • presto中有一種叫runtimeFilter的方式。

對於join過程, 我們可以:

  1. 將小表的id進行一定的壓縮處理(例如雜湊之後取前x位)
    這樣可以減少傳輸的資料量。
  2. 然後將這塊資料傳輸給大表所在的節點, 進行提前的簡單join篩選, 這樣就可以提前過濾掉很多的沒必要通過網路輸出的資料。

4個優化方法,讓你能瞭解join計算過程更透徹

以上僅僅只是最基礎的join優化過程, 而在海量資料、高效能、高安全、跨網路的複雜場景中, 關於join計算還會有更多的挑戰。

因此可以關注華為可信智慧計算TICS服務,專注高效能高安全的聯邦計算和聯邦學習,推動跨機構資料的可信融合和協同,安全釋放資料價值。

 

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

相關文章