一、什么是數(shù)據(jù)傾斜
簡單的講,數(shù)據(jù)傾斜就是我們在計算數(shù)據(jù)的時候,數(shù)據(jù)的分散度不夠,導致大量的數(shù)據(jù)集中到了集群中的一臺或者幾臺機器上計算,而集群中的其他節(jié)點空閑。這些傾斜了的數(shù)據(jù)的計算速度遠遠低于平均計算速度,導致整個計算過程過慢。
1.1 數(shù)據(jù)傾斜
相信大部分做數(shù)據(jù)的童鞋們都會遇到數(shù)據(jù)傾斜,數(shù)據(jù)傾斜會發(fā)生在數(shù)據(jù)開發(fā)的各個環(huán)節(jié)中,比如:
1.用Hive算數(shù)據(jù)的時候reduce階段卡在99.99%
2.用SparkStreaming做實時算法時候,一直會有executor出現(xiàn)OOM的錯誤,但是其余的executor內(nèi)存使用率卻很低。
3.這些問題經(jīng)常會困擾我們,辛辛苦苦等了幾個小時的數(shù)據(jù)就是跑不出來,心里多難過啊。
1.2 千億級
為什么要突出這么大數(shù)據(jù)量?先說一下筆者自己最初對數(shù)據(jù)量的理解:
數(shù)據(jù)量大就了不起了?數(shù)據(jù)量少,機器也少,計算能力也是有限的,因此難度也是一樣的。憑什么數(shù)據(jù)量大就會有數(shù)據(jù)傾斜,數(shù)據(jù)量小就沒有?
這樣理解也有道理,但是比較片面,舉兩個場景來對比:
公司一:總用戶量1000萬,5臺64G內(nèi)存的的服務(wù)器。
公司二:總用戶量10億,1000臺64G內(nèi)存的服務(wù)器。
兩個公司都部署了Hadoop集群。假設(shè)現(xiàn)在遇到了數(shù)據(jù)傾斜,發(fā)生什么?
1.公司一的數(shù)據(jù)分析師在做join的時候發(fā)生了數(shù)據(jù)傾斜,會導致有幾百萬用戶的相關(guān)數(shù)據(jù)集中到了一臺服務(wù)器上,幾百萬的用戶數(shù)據(jù),說大也不大,正常字段量的數(shù)據(jù)的話64G還是能輕松處理掉的。
2.公司二的數(shù)據(jù)分析師在做join的時候也發(fā)生了數(shù)據(jù)傾斜,可能會有1個億的用戶相關(guān)數(shù)據(jù)集中到了一臺機器上了(相信我,這很常見)。這時候一臺機器就很難搞定了,最后會很難算出結(jié)果。
二、數(shù)據(jù)傾斜長什么樣
下面會分幾個場景來描述一下數(shù)據(jù)傾斜的特征,方便讀者辨別。由于Hadoop和Spark是最常見的兩個計算平臺,下面就以這兩個平臺說明。
2.1 Hadoop中的數(shù)據(jù)傾斜
Hadoop中直接貼近用戶使用使用的時Mapreduce程序和Hive程序,雖說Hive最后也是用MR來執(zhí)行(至少目前Hive內(nèi)存計算并不普及),但是畢竟寫的內(nèi)容邏輯區(qū)別很大,一個是程序,一個是Sql,因此這里稍作區(qū)分。
具體表現(xiàn):
Hadoop中的數(shù)據(jù)傾斜主要表現(xiàn)在:Reduce階段卡在99.99%,一直不能結(jié)束。
這里如果詳細的看日志或者和監(jiān)控界面的話會發(fā)現(xiàn):
- 有一個多幾個Reduce卡住
- 各種container報錯OOM
- 異常的Reducer讀寫的數(shù)據(jù)量極大,至少遠遠超過其它正常的Reducer
- 伴隨著數(shù)據(jù)傾斜,會出現(xiàn)任務(wù)被kill等各種詭異的表現(xiàn)。
Hive的數(shù)據(jù)傾斜,一般都發(fā)生在Sql中g(shù)roup by和join on上,而且和數(shù)據(jù)邏輯綁定比較深。
2.2 Spark中的數(shù)據(jù)傾斜
Spark中的數(shù)據(jù)傾斜也很常見,這里包括Spark Streaming和Spark Sql,表現(xiàn)主要有下面幾種:
- Executor lost,OOM,Shuffle過程出錯
- Driver OOM
- 單個Executor執(zhí)行時間特別久,整體任務(wù)卡在某個階段不能結(jié)束
- 正常運行的任務(wù)突然失敗
注意,在Spark streaming程序中,數(shù)據(jù)傾斜更容易出現(xiàn),特別是在程序中包含一些類似sql的join、group這種操作的時候。 因為Spark Streaming程序在運行的時候,我們一般不會分配特別多的內(nèi)存,因此一旦在這個過程中出現(xiàn)一些數(shù)據(jù)傾斜,就十分容易造成OOM。