Hive的配置詳解和日常維護
一.Hive的參數配置詳解
1>.mapred.reduce.tasks
默認為-1。指定Hive作業的reduce task個數,如果保留默認值,則Hive 自己決定應該使用多少個task。
2>.hive.mapred.mode
2.x下的默認值為strict,1.x以及之前的版本默認值為nonstrict。如果 設為strict,Hive將禁止一些危險的查詢:分區表未用分區字段篩選; order by語句后未跟limit子句;join后沒有on語句從而形成笛卡爾積。
3>.hive.merge.mapfiles
默認為true。如果設置為true,Hive在只有map(沒有reduce)的作業結束時合並小文件,否則不會進行合並。
4>.hive.merge.mapredfiles
默認為false。如果設置為true,Hive在map/reduce作業結束時合並小文 件,否則不會進行合並。注意和上一個參數區別。
5>.hive.exec.parallel
默認為false。是否啟用作業並發執行,如果啟用,一些不沖突的task可 以同時執行,例如在join語句中訪問不同表獲取數據的task
6>.hive.exec.reducers.bytes.per.reducer
該參數在0.14.0之前默認為1,000,000,000(約1GB),在0.14.0及以后默 認為256,000,000(約256MB)。該參數控制每個reducer平均處理的字節 數,默認值不一定適合所有的情況,應該根據企業內Hive作業通常處理的 數據量、集群節點數等參數來酌情配置。
7>.hive.exec.dynamic.partition
該參數在0.9.0前默認為false,在0.9.0及以后默認為true。Hive課中介 紹過此參數,用於控制是否啟用動態分區特性,如果啟用,往分區表中插 入數據而指定的分區又不存在時,可以自動創建分區。
8>.hive.exec.dynamic.partition.mode
默認為strict。如果設為該值,則在使用動態分區時用戶需要指定至少一 個靜態分區列,如果設為nonstrict則無此要求。
9>.hive.exec.mode.local.auto
默認為false。控制Hive是否在輸入文件較小時啟用本地運行特性,默認 不開啟,一般不建議開啟。還有兩個參數 hive.exec.mode.local.auto.inputbytes.max和 hive.exec.mode.local.auto.input.files.max兩個參數可以控制總輸入 字節數和總輸入文件個數的門限。
10>.hive.auto.convert.join
該參數在0.11.0之前默認為false,在0.11.0及以后默認為true。控制 Hive是否根據輸入表的大小將普通join(reduce端)自動轉化為map join, 較高版本默認都是開啟的,不建議關閉。
11>.hive.exec.scratchdir
用於儲存map/reduce階段的查詢計划和中間輸出數據的HDFS路徑,默認值 被調整過多次,在0.14.0后是/tmp/hive。還有一個參數 hive.scratch.dir.permission用於創建該目錄時的權限,默認為700。這 個路徑通常不會調整,但需要心里有數,很多時候hive sql異常終止時, 會在該路徑下遺留大量中間數據,時間長了浪費HDFS空間,建議定期清理。
12>.hive.map.aggr
默認為true。在帶GROUP BY的查詢中是否啟用map端聚合。不需要調整。
13>.hive.metastore.warehouse.dir
默認為/user/hive/warehouse,用於配置Hive默認的數據文件存儲路徑, 這是一個HDFS路徑。可按需調整。
14>.hive.default.fileformat
默認為TextFile。在CREATE TABLE語句中使用的默認文件存儲格式,可選 值有TextFile,SequenceFile,RCfile,ORC,Parquet。一般來說,為了 調試方便(可以直接將文件下到本地並用文本編輯器打開),在測試時不 會改動該參數,在上線后可酌情修改,即使不修改,也可以使用CREATE TABLE ... STORED AS TEXTFILE|SEQUENCEFILE|RCFILE|ORC|... 這樣的 語法對每個表單獨設置文件格式。
15>.hive.exec.compress.output
默認為false。控制hive sql的輸出是否要壓縮。一般不修改該值,而是 需要壓縮時對某條sql單獨指定。
16>.hive.exec.compress.intermediate
默認為false。控制非最終結果的中間stage的輸出是否要壓縮。一般不修 改該值,而是需要壓縮時對某條sql單獨指定。
17>.hive.execution.engine
默認為mr,但是在2.0.0后被標記為deprecated。決定Hive的執行引擎, 可選值有mr,tez,spark。在2.0.0后標記過期的原因是新版本的Hive已 經將Spark作為默認的執行引擎,只有在找不到Spark時才會回到用 MapReduce執行。
18>.hive.exec.reducers.max
要使用的 reducer 的最大數量。如果配置參數 Hive Reduce Tasks 為負,則 Hive 會將 reducer 數量限制為此參數的值。我集群的默認值是:1099,修改后的值為250。
19>.hive.map.aggr.hash.percentmemory
map端聚合時hash表所占用的內存比例,默認0.5,這個在map端聚合開啟后使用,我們可以設置為0.6
20>.hive.cli.print.header
查詢輸出時是否打印名字和列,默認是false.
21>.hive.cli.print.current.db
hive的提示里是否包含當前的db,默認是false.
22>.其他參數
詳情請參考:https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties
23>.以下幾個參數是我生產環境線上的hive調優策略,僅供參考
<property> <name>hive.cli.print.current.db</name> <value>true</value> <description>Whether to include the current database in the Hive prompt.</description> </property> <property> <name>hive.exec.reducers.max</name> <value>250</value> </property> <property> <name>hive.exec.parallel</name> <value>true</value> </property> <property> <name>hive.auto.convert.join</name> <value>false</value> </property> <property> <name>hive.exec.parallel.thread.number</name> <value>3</value> </property> <property> <name>hive.mapjoin.maxsize</name> <value>10000000</value> </property> <property> <name>hive.mapjoin.followby.gby.localtask.max.memory.usage</name> <value>0.60</value> </property> <property> <name>hive.map.aggr.hash.percentmemory</name> <value>0.60</value> </property>
二.Hive的日常運維
1>.SQL問題
根據Hive的執行機制,如果遇到SQL出現問題的情況,我們首先需要查看日志,然后根據錯誤出現的層面不同進行處理: (1)如果是執行引擎層面的錯誤,會拋出相應的MapReduce或Spark異常。 (2)如果並非第1點的問題,基本都是SQL層面的錯誤。此類問題也分為多種:如HiveSQLException: Error while compiling statement: No privilege ...是在校驗權限時出現權限不足的問題;FAILED: SemanticException [Error xxxx] 是出現Hive SQL書寫語法上的問題; 等等。解決此類問題,還是需要有一些Hive SQL使用的基礎知識,區分第1類問題還是第2類問題非常簡單,看拋出異常的時間即可,如SQL開始執行的一兩秒內即拋出異常,基本都是SQL層面問題, 比較長時間才拋出來的基本都是執行引擎層面的問題。 (3)慢SQL問題。嚴格來說這部分問題不應由運維處理(然而大數據領域並不像關系型數據庫一樣有專門的DBA方向)。作為技能上的備份和補充, 運維方向同學可補充一些Hive特有的機制,如map端連接、分區、分桶、 map端聚合等等,以及explain等語句的用法,在別人搞不定時可有效介入。
2>.元數據管理
Hive運維的另一項重要工作是元數據管理。雖然Hive元數據出現問題的概 率較低,但出問題的后果比較嚴重,因此我們進行一下深入學習。 與Hive元數據相關的主要服務有兩個,每個又有兩種模式: 元數據數據庫(用於儲存元數據),分為本地/內置的元數據庫(Derby) 和遠程元數據庫(利用其他支持的關系型數據庫)。 數據服務器(用於提供元數據查詢服務,響應修改請求),分為本地 /內置的元數據服務器和遠程元數據服務器。 核心配置有以下幾個: javax.jdo.option.ConnectionURL 元數據庫的JDBC連接串。 javax.jdo.option.ConnectionDriverName
元數據庫的JDBC驅動類名。 hive.metastore.uris
元數據服務器的URI,以thrift開頭,如果啟動了多個元數據服務器(通 常因為HA考慮),則可用逗號分隔填寫多個URI。 hive.metastore.warehouse.dir
默認為/user/hive/warehouse,用於配置Hive默認的數據文件存儲路徑, 這是一個HDFS路徑。可按需調整。
元數據庫的可用性:
使用Mysql的主從或主主復制可以實時同步數據,實在沒有這樣的條件,至少需要定期備份。
3>. 想使用遠程的Mysql數據庫作為元數據庫,並使用遠程元數據服務器需要經歷以下步驟
1>.安裝Mysql,略 2>.在希望啟動遠程元數據服務器的主機上,修改hive配置文件的以下項: javax.jdo.option.ConnectionURL 設為jdbc:mysql://<host name>/ <database name>?createDatabaseIfNotExist=true javax.jdo.option.ConnectionDriverName 設為com.mysql.jdbc.Driver javax.jdo.option.ConnectionUserName 設為<user name> javax.jdo.option.ConnectionPassword 設為<password> 3>.在該機器上,執行hive --service metastore 啟動元數據服務器(如 果想使用非默認的端口,還可以加-p參數) 4>.在客戶端主機上,修改hive配置文件中的以下項: hive.metastore.uris 設為thrift://<host_name>:<port> ,其中 hist_name和port為元數據服務器的參數 hive.metastore.warehouse.dir 設為一個HDFS路徑,可以不修改 5>.嘗試連接hive
4>.元數據庫的升級
不同大版本的Hive間元數據庫的schema是不一致的,因此升級Hive時很重要的一步是升級元數據庫。Hive自帶一個schematool工具,可以執行元數據庫相關的各種運維操作,如對derby的元數據庫,從 0.10.0升級到用戶的版本(假設為0.13.0),可用如下命令:
$ schematool -dbType derby -upgradeSchemaFrom 0.10.0
Metastore connection URL: jdbc:derby:;databaseName=metastore_db;create=true
Metastore Connection Driver : org.apache.derby.jdbc.EmbeddedDriver
Metastore connection User: APP
Starting upgrade metastore schema from version 0.10.0 to 0.13.0
Upgrade script upgrade-0.10.0-to-0.11.0.derby.sql
Completed upgrade-0.10.0-to-0.11.0.derby.sql Upgrade script
upgrade-0.11.0-to-0.12.0.derby.sql
Completed upgrade-0.11.0-to-0.12.0.derby.sql
Upgrade script upgrade-0.12.0-to-0.13.0.derby.sql
Completed upgrade-0.12.0-to-0.13.0.derby.sql
schemaTool completed
三.擴展
參數的詳細解釋和未提及的參數可參考官方文檔: https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties 閱讀元數據運維的官方文檔:https://cwiki.apache.org/confluence/display/Hive/AdminManual+Metastore+Administration。