hive的调优操作
1、 hive.fetch.task.conversion=more 該屬性修改為 more 以后,在全局查找、字段查找、limit 查找等都不走mapreduce
2、 當輸入數據量很小的時候, 查詢觸發執行任務時消耗可能會比實際 job 的執行時間要多的多, Hive可以通過本地模式在單臺機器上處理所有的任務。對于小數據集,執行時間可以明顯被縮短
//開啟本地 mr hive.exec.mode.local.auto=true?// 設置 local mr 的最大輸入數據量,當輸入數據量小于這個值時采用 local mr 的方式,默認為 134217728,即 128M hive.exec.mode.local.auto.inputbytes.max=50000000;// 設置 local mr 的最大輸入文件個數,當輸入文件個數小于這個值時采用 local mr 的方式,默認為 4 hive.exec.mode.local.auto.input.files.max=10;3、 有時 join 超時是因為某些 key 對應的數據太多,而相同 key 對應的數據都會發送到相同的 reducer 上,從而導致內存不夠。
所以應該首先處理掉這些異常值, 比如過濾key為空值,或者為空值的key加上特殊標識+隨機數的方式,然后到reduce階段再去掉標識進行聚合一次操作。
4、 MapJoin操作,當在Reducer端聚合的時候可能會由于Key傾斜太多導致某幾個Key處理很慢。MapJoin的時候會把小表廣播到各個Map端內存中出緩存直接在Map端進行join操作。
// 開啟Mapper端join,默認為 true hive.auto.convert.join = true;?// 大表小表的閥值設置(默認 25M 一下認為是小表): hive.mapjoin.smalltable.filesize=25000000;5、 Group BY 操作。默認情況下,Map 階段同一 Key 數據分發給一個 reduce,當一個 key 數據過大時就傾斜了。
// 開啟Map端join操作 hive.map.aggr = true// 在 Map 端進行聚合操作的條目數目 hive.groupby.mapaggr.checkinterval = 100000// 當選項設定為 true,生成的查詢計劃會有兩個 MR Job。第一個 MR Job 中,Map 的輸出結果會隨機分布到 Reduce 中,每個 Reduce 做部分聚合操作,并輸出結果,這樣處理的結 // 果是相同的 Group By Key 有可能被分發到不同的 Reduce 中,從而達到負載均衡的目的;第二個 MR Job 再根據預處理的數據結果按照 Group By Key 分布到 Reduce 中(這個過程可以 // 保證相同的 Group By Key 被分布到同一個 Reduce 中),最后完成最終的聚合操作。 hive.groupby.skewindata = true
6、 Count(Distinct) 去重統計
數據量小的時候無所謂,數據量大的情況下,由于 COUNT DISTINCT 操作需要用一個Reduce Task 來完成,這一個 Reduce 需要處理的數據量太大,就會導致整個 Job 很難完成,
一般 COUNT DISTINCT 使用先 GROUP BY 再 COUNT 的方式替換
7、 盡量避免笛卡爾積,join 的時候不加 on 條件,或者無效的 on 條件,Hive 只能使用 1個 reducer 來完成笛卡爾積
8、 行列過濾
列處理:在 SELECT 中,只拿需要的列,如果有,盡量使用分區過濾,少用 SELECT *。
行處理:在分區剪裁中,當使用外關聯時,如果將副表的過濾條件寫在 Where 后面,那么就會先全表關聯,之后再過濾。
9、 動態分區調整?
// 開啟動態分區功能(默認 true,開啟) hive.exec.dynamic.partition=true// 設置為非嚴格模式(動態分區的模式,默認 strict,表示必須指定至少一個分區為, 靜態分區,nonstrict 模式表示允許所有的分區字段都可以使用動態分區。) hive.exec.dynamic.partition.mode=nonstrict// 在所有執行 MR 的節點上,最大一共可以創建多少個動態分區 hive.exec.max.dynamic.partitions=1000// 在每個執行 MR 的節點上,最大可以創建多少個動態分區。該參數需要根據實際的數據來設定。 hive.exec.max.dynamic.partitions.pernode=100// 整個 MR Job 中,最大可以創建多少個 HDFS 文件。 hive.exec.max.created.files=100000// 當有空分區生成時,是否拋出異常。一般不需要設置。 hive.error.on.empty.partition=false10、調整Map任務數,由于Hive的一個Map對應于一個BlockSize大小的文件,所以我們可以通過修改這個值增大或者減小Map數據。
// 小文件合并 hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;// 修改每個切片的最大的大小 mapreduce.input.fileinputformat.split.maxsize=100;11、 調整Reduce任務數目// 每個 Reduce 處理的數據量默認是 256MB hive.exec.reducers.bytes.per.reducer=256000000// 每個任務最大的 reduce 數,默認為 1009 hive.exec.reducers.max=100911、 并行執行
//打開任務并行執行 hive.exec.parallel=true;?//同一個 sql 允許最大并行度,默認為 8。 hive.exec.parallel.thread.number=16;?
12、 JVM 重用,JVM重用可以使得 JVM 實例在同一個 job 中重新使用 N 次。
這個功能的缺點是,開啟 JVM 重用將一直占用使用到的 task 插槽,以便進行重用,直到任務完成后才能釋放。如果某個“不平衡的”job 中有某幾個 reduce task 執行的時間要比其
他 Reduce task 消耗的時間多的多的話,那么保留的插槽就會一直空閑著卻無法被其他的 job使用,直到所有的 task 都結束了才會釋放。
13、推測執行
Hadoop 采用了推測執行(Speculative Execution)機制,它根據一定的法則推測出“拖后腿”的任務,并為這樣的任務啟動一個備份任務,
讓該任務與原始任務同時處理同一份數據,并最終選用最先成功運行完成任務的計算結果作為最終結果。
14、小文件合并
當數據表格式為ORC的分區表的時候可以通過以下命令進行小文件合并:
# 該命令會把小的orc文件合并成單個文件最大的大小,減少小文件的數目 alter table dwd.dwd_pass_log_1min_analysis_data_di partition (dt=20180101) concatenate;15、sqoop導入數據到hive的orc分區表中
sqoop import \ --connect "$mysql_db_con" \ --username "$mysql_db_user" \ --password "$mysql_db_pwd" \ --query "$query_sql" \ // 自定義sql查詢,注意: 必須加 and \$CONDITIONS 類似于 1=1這種寫法 --fields-terminated-by "\001" \ // 導出的字段分隔符為\001 --lines-terminated-by "\n" \ // 導出數據行分隔符 --escaped-by '$' \ --hive-import \ --hive-overwrite \ // 覆蓋寫的方式 --hive-database "dwd" \ // 寫入的庫名 --hive-table "dwd_paas_log_1min_analysis_data_di_2020" \ // 將要寫入的表名 --hive-partition-key "dt" \ // 分區鍵 --hive-partition-value "$dt" \ // 分區的值 --split-by "$split_id" \ // 數據并行導出的鍵 --target-dir "$table_dir" \ // 數據導出時候的臨時目錄 --m 12 \ // 數據導出并行度 --delete-target-dir \ // 導出完成后刪除臨時目錄 --hive-drop-import-delims \ --null-string '\\N' \ --null-non-string '\\N'?
總結
- 上一篇: 函数柯里化-浅尝
- 下一篇: 如何在微信、抖音上线一款小游戏?版权认证