啥是數據傾斜?就是數據歪啦!
- 2019 年 12 月 18 日
- 筆記
我們在《業務開發中你用到了哪些算法?》中,一起暢聊了 hash 算法在實際研發中的應用,並且提出了「數據傾斜是怎麼回事?」的疑問;由於按照一猿小講的風格,絕不能讓大家止於應用,於是在《業務開發中你用到了哪些算法(續)?》中,一起把主題又升華了一下。
雖然在以往的文章提出了「數據傾斜是怎麼回事呢?」的疑問,卻遲遲未給大家分享答案。
面試官:啥是數據傾斜? 懵B 哥:數據傾斜就是數據歪啦! 面試官:然後呢? 懵B 哥:沒有然後啦! 氣氛相當之凝重,尬聊……
為了避免以上尬聊,那麼不妨一起嘗試把這個事聊透亮,萬一你在面試的時候有幸被問到呢?
話不多說,請坐穩扶好,本期不燒腦的分享正式開始。
01. 「二八」法則

(圖片來源於網絡)
從朋友圈裡拽了一張圖,剛好吻合咱們今天分享的主題。如上圖總結,20% 的人掌握世上 80% 的財富,而 80% 的人掌握世上 20% 的財富,言外之意財富在世上的分配是不平衡的,其實生搬硬套再講的高大尚一點就是存在數據傾斜。

(圖片來源於網絡)
02. 數據傾斜
「二八」法則已經闡明了生活中的數據傾斜,那在計算機的世界裏是否會存在數據傾斜呢?答案是肯定的。
想想線上的那些事兒。
1. 線上服務器,始終有幾台超負荷工作。想想上篇分享為什麼建議後端研發人員維護 Session,而不是 Nginx 配置 ip_hash 的策略來解決 Session 共享的問題。 2. 分佈式緩存環境下,由於數據分散度不夠,導致大量的數據集中到了一台或者幾台服務節點上。 3. MapReduce 場景下,Mapper 執行完後,默認會根據 (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks 進行分區,如果 key 的 hash 值重複了,即會存在大量 key,始終讓一個 Reducer 去處理的情形。
想想身邊的那些事兒。
在社交媒體網站上,一些名人用戶有數百萬粉絲,當其發佈一些熱點事件時可能會一起異常訪問風暴。例如,某某官宣結婚,某浪微博服務器又宕機了的消息,瞬間會出現在你的視野之中。
其實還有很多這樣的場景,但是都說明了一個問題「一台機器超負荷,一台機器零負荷;一部分數據多,一部分數據少」。其實生活中也會經常聽到有人抱怨道「忙的忙死,閑的閑死」,不過話又說回來,如果工作中你比較忙,那麼恭喜你,從以上的種種場景分析足矣說明你非常重要,哈哈,扯遠啦。
用一句話嘗試說清楚數據傾斜,其實是由於數據的 key 的分攤嚴重不均,導致的一部分分攤的數據很多,一部分數據分攤的很少的尷尬局面。
面對這種尷尬的局面,該如何解決呢?
03. 辨證施藥
看到「二八」法則,我們知道財富在世上的分配是不平衡的,但是你有沒有辦法去扭轉它呢?如果你真有方式可以扭轉,那大家一定要抱緊你大腿,往往扭轉不太現實,但是大家能做的就是努力擠進那 20% 的塔尖(遠方的希望還是有的,萬一實現了呢),言外之意扭轉數據傾斜的方式,需要改變方式。
最近在看一本書《數據密集型應用系統設計》,書中提到,大多數的系統今天仍然無法自動消除高度傾斜的負載,而只能通過應用層來減輕傾斜的程度。
例如,在面對某某官宣的熱點問題,熱點關鍵字可能是名人的用戶 ID 或者正在評論的事件 ID,一個簡單的技術就是在關鍵字的開頭或者結尾處添加一個隨機數,因為一個兩位數的十進制隨機數,就可以將關鍵字的寫操作,分佈到 100 個不同的關鍵字上,從而分配到不同的分區上。但是隨之而來的問題是,之後的任何讀取都需要做些額外的工作,必須從100 個關鍵字中讀取數據然後進行合併。
例如,在面對 MapReduce 默認分區HashPartitioner,若在實際應用中表現不太良好時,那不妨看看數據,然後根據業務自定義 Partitioner 的實現。
說白了,數據傾斜沒有一勞永逸的方式可以解決,需要辯證施藥,在不同的場景下,應對的方案也不盡相同。
最後,以《數據密集型應用系統設計》書中的一段話結束本次的分享。也許將來某一天,系統會自動檢測負載傾斜情況,然後自動處理這些傾斜的負載。但是截至目前,仍然需要開發者自己結合實際應用來綜合權衡。