SQOOP可能會導致HDFS分片數量過多的總結

使用多少個mapreduce來進行移植數據,例如:

./sqoop import --create-hive-table  --hive-import --hive-overwrite   --connect jdbc:oracle:thin:@XXX.XXX.XXX.XXX:1521:orcl --username name --password pwd --table tablename --hive-database hivedatabasename -m 5

上面使用了5個任務,然後數據在每個任務不滿128M的時候,存儲文件也會分成5份,在數據量不是很大的情況下,還是應該只用1個任務來跑,這樣文件的分片比較少,爲什麼要分片數量少呢?

spacer.gifwKioL1bpFV3wc9xiAAA-KO-6ON4643.png

比如下面就是用1個任務跑的

spacer.gifwKiom1bpFPKygAFpAAAnMIU4el8164.png

當後面用sparksql進行表數據的清洗、篩選和合並的時候,

例如我們把每日的數據最終合併到年表中,當使用

insert into tableyear select * from tableday的方式在sparksql中執行時,hive會自動把日表的文件拷貝到年表中,就會出現以下奇景:

spacer.gifwKioL1bpFa_AKwwgAAB-y-x9wF8734.png

我們發現全部是拷貝的

然後當我們在sparksql中執行某些任務的時候,那麼就需要從每個數據分片查詢,這都是時間,以2個月爲例,每天用5個mapreduce進行sqoop移植數據,最終產生了300多個數據分片,然後執行的sparksql的count表數據的時候,我們就會發現產生了300多個Task

spacer.gifwKioL1bpFdyT_HKOAAHzRbCyIc4521.png

spacer.gif

spacer.gif

當存在300多個數據分片的時候進行count,我們發現就算那個分片就算是0B,至少也會損耗將近10ms的時間,如果能將分片變成1/5,比如少200個分片,以上面例子爲例節省的時間就可能是2s,當然這種計算不一定合理,但至少印證了數據分片數量過多對速度上的影響。

上面的數據量大概是600萬,花了5秒。

而我們另外一個數據600多萬,比它還多一點數據,執行的時候第一次2秒左右,後面每次執行都1秒鐘都不到,就是因爲數據分片少

spacer.gifwKiom1bpFmjCf7JFAAA_9gOnFwM545.png

spacer.gifwKioL1bpFzCB4K6aAABJre-r4UI216.png

因爲執行的任務數量少了,所以效率大幅度提高了:

wKiom1bpFnzxdPhwAAFAIPEGE6c646.pngspacer.gif



總結:



如果數據比較少的情況下,我們更加建議,在關係型數據庫將數據合併之後再使用sqoop移植,比如oracle我們上面的表,1天的數據本身就只有10萬條左右,大小在70M左右,根本沒滿128M,這個時候就算一天一個HDFS文件,在後續合併區間段(比如歷史所有5年的數據全部放在一個表)太長的情況下,都會顯得浪費,不如把1個月的數據300萬條首先的關係型數據庫合併到大表,大小總共就1個G,如果分配合理,最終在hdfs中只需要產生10個左右的數據分片,2個月產生20個,相比上面我們產生了300多個數據分片,最終的效率肯定不可同日而語!!!

當數據量比較多,比如一天數據本身本身就有500萬甚至上千萬數據的時候,一天的大小可能就會與幾個G甚至幾十個G,那麼這個時候我們就算用多個mapreduce任務也沒關係,當然任務還是不能太多,不然很可能出現每個任務的最後產生的文件離128M差距太多,還是會對性能產生一定的影響!!!

性能優化看來是一條瘋狂的道路!!!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章