問題描述
使用spark寫複雜sql時,我們經常會遇到兩個尷尬的情況:
對於第一種情況,會導致我們沒辦法充分利用我們已有的核,所以速度很慢。
對於第二種情況,則會大量浪費排程時間。比如你有100萬個檔案,假設只有100個核,那麼需要排程一萬輪,每輪排程除了排程自身的消耗,還有很多額外的消耗。在沒有shuffle的情況下,會導致寫太多檔案,本身就浪費效能,如果有shuffle,則對這麼多map進行合併,本身也帶來額外消耗。所以最佳辦法是在讀取的時候就能生成較少的分割槽,從而減少開銷。
大檔案優化讀取優化
大檔案優化讀取需要關注兩個引數:
第乙個引數是針對session有效的,也就是因為這你在讀的時候設定就會立刻生效。在沒有第二個引數配合的情況下,就已經能夠增加分割槽數了,缺點是,分割槽裡的資料可能不會很均勻,因為均勻程度也會受到第二個引數的影響。spark.files.maxpartitionbytes= 預設128m
parquet.block.size= 預設128m
然而,第二個引數需要寫入的時候就配置上。所以大家有條件可以設定下,方便遇到檔案較大,然後單條記錄又很小的情況下,查詢可以更靈活控制。
小檔案讀取優化
小檔案讀取首先有基礎引數要設定(其中parquet已經是預設開啟的),分別是針對parquet格式和orc的。
只要是 parquet 或者 orc,無論是 hive 表還是 datasource,預設都走 filescan,都支援合併。所以大部分情況,這兩個引數大家可以當做不存在。spark.sql.hive.convertmetastoreparquet=true (預設已經為true)
spark.sql.hive.convertmetastoreorc=true
接下來就是通過另外兩個引數來控制怎麼進行小檔案合併了(多個檔案合併成乙個分割槽):
我們簡單解釋下這兩個引數(注意他們的單位都是bytes):spark.files.maxpartitionbytes= 預設128m
spark.files.opencostinbytes= 預設4m
所以理論上你可以將opencostinbytes再設定大一點,減少分割槽讀取。
Spark避免小檔案
select from table1 distribute by rand select repartition 200 a.from table1 a select coalesce 200 a.from table1 a 用 coalesce或者repartition,num 1.0 df.co...
Hadoop小檔案優化
1 影響namenode的壽命,因為檔案元資料儲存在namenode的記憶體中 2 影響計算引擎的任務數量,比如每個小的檔案都會生成乙個map任務 1 合併小檔案 對小檔案進行歸檔 har 自定義inputformat將小檔案儲存成sequencefile文 件。2 採用combinefileinp...
Spark讀取檔案
spark預設讀取的是hdfs上的檔案。如果讀取本地檔案,則需要加file usr local spark readme.md。測試時候發現,本地檔案必須在spark的安裝路徑內部或者平行 讀取hdfs檔案,可以這樣指定路徑 hdfs ns1 tmp test.txt。如果不指定任何字首,則使用hd...