今天遇到一個問題,spark應用中在一個循環裏執行sql,每一個sql都會向一張表寫入數據,好比html
insert overwrite table test_table partition(dt) select * from test_table_another;web
除了執行sql沒有其餘邏輯,每一個sql都會對應1個job,在spark web ui上看到job和job之間會停頓幾分鐘,而且很是有規律,任何兩個job之間都會停頓,是否是很神奇?sql
答案揭曉:數據庫
spark在執行insert overwrite table partition的時候,分爲兩個部分,一個是執行select(讀數據),一個是執行load partition(寫數據),具體詳見執行計劃;ui
每一個sql對應1個job,這個job執行的select部分(讀數據),不包含load partition部分(寫數據),由於spark爲了兼容hive,直接使用hive的元數據庫,全部ddl操做都是經過反射直接調用hive的代碼(spark2.1依賴的是hive1.2),這個過程並不包含在spark job中,因此看起來job執行完以後停頓了幾分鐘才執行下個job,這裏停頓的幾分鐘實際上是在作load partition操做(寫數據);spa
這裏還有另一個問題,hive1.2在loadPartition刪除文件時是串行操做,很是慢,這個問題在hive2時改成線程池解決,具體代碼及問題解析詳見:http://www.javashuo.com/article/p-nknezqoq-dz.html線程