1、問題示例
(1)hive創建表
hive (test)> create table t1(id int,name string)
> clustered by (id) into 8 buckets
> stored as orc tblproperties ('transactionl'='true');
OK
Time taken: 13.342 seconds
(2)插入數據報錯
insert into t1 values (1,'aaa');
Query ID = grid_20211027110417_1a2f8a7b-2837-4c88-9a28-00a8b679e029
Total jobs = 2
Launching Job 1 out of 2
Number of reduce tasks determined at compile time: 8
In order to change the average load for a reducer (in bytes):
set hive.exec.reducers.bytes.per.reducer=<number>
In order to limit the maximum number of reducers:
set hive.exec.reducers.max=<number>
In order to set a constant number of reducers:
set mapreduce.job.reduces=<number>
Cannot run job locally: Number of reducers (= 8) is more than 1
Starting Job = job_1635258384646_0002, Tracking URL = http://master:8088/proxy/application_1635258384646_0002/
Kill Command = /home/grid/Hadoop/hadoop-3.3.1/bin/mapred job -kill job_1635258384646_0002
Hadoop job information for Stage-1: number of mappers: 0; number of reducers: 0
2021-10-27 11:10:06,987 Stage-1 map = 0%, reduce = 0%
Ended Job = job_1635258384646_0002 with errors
Error during job, obtaining debugging information...
FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask
MapReduce Jobs Launched:
Stage-Stage-1: HDFS Read: 0 HDFS Write: 0 FAIL
Total MapReduce CPU Time Spent: 0 msec
(3)沒有成功插入數據
hive (test)> select * from t1;
OK
Time taken: 8.98 seconds
2、問題剖析
(1)從上面報錯結果可知,hive成功創建了表,但卻不能向表中插入數據;
(2)使用Spark-sql再次向hive創建的表插入數據,卻能成功插入,但在hive中就是不行;
(3)使用hive向非桶表插入數據,是可以的;
(4)該問題,筆者已經解決,筆者曾試用過多種辦法都沒有解決,是在一次偶然情況解決的。由於解決過程是在反反復復測試和修改各種參數中,無意中測試成功的,反過來推測造成上述其原因如下(未進一步去檢驗):
A、造成上述根本原因是Hadoop主節點(master)內存不足,就是用於ResourceManager的節點,至少需要4G的運行內存,當時筆者設置Hadoop運行內存為3G。其原因是在向hive創建的桶表插入數據時,hive計算引擎設置使用mr引擎(即mapreduce)時,而使用Mapreduce時,需要4G內存才能運行。注意:非桶表或小數據,則不需要這么多內存。向桶表插入數據,那怕只是1條數據,MapReduce也都需要足夠的內存。那是因為ResourceManger本身運行就占用了很大一部分內存,再執行計算任務時,就需要更多的內存。
B、Spark-sql執行桶表插入數據時,計算引擎是Spark本身,不需要額外占用過多的內存,且數據本身在內存中執行交換,所以可以執行成功,效率很高。
C、Hive使用mr作為計算引擎時,很是消耗內存,尤其是桶表。
D、因此給新手已經建議,初次配制hadoop集群時,主節點的內存一定要大一些,至少也需要4G,否則就會出現這種坑。
E、使用hive時,盡可能避免使用mr作為計算引擎,可以修改為spark或tez,可提高運行效率,但需要額外配制相關參數。
3、解決方案
(1)方案1:設置參數為:hive.exec.mode.local.auto=true
hive (test)> set hive.exec.mode.local.auto=true;
結果行不通,筆者已從“hive-siet.xml”配置了該參數。這是一個錯誤的方向,是筆者最初以為是hive參數配制不對導致的問題。
(2)方案2:
找到Hadoop集群配制文件yarn-site.xml,設置參數:yarn.nodemanager.resource.memory-mb,參數設置示例如下:4096即為4G。
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>4096</value>
</property>
另外一個與之相關的參數:yarn.scheduler.minimum-allocation-mb,筆者設置為2G,但未檢驗是否會影響性能。
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>2048</value>
</property>