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