Hive使用常见问题&&优化

本文汇总了Hive使用过程中的常见问题及解决办法。涵盖内存溢出、执行动态分区报错、创建文件数过多等问题,针对不同阶段和报错信息,给出了调整参数、修改表属性、检查语法等多种解决方式,还提及Hive UDF参考等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1)内存溢出
map阶段
解决:一般存在MapJoin,设置参数set hive.auto.convert.join = false转成reduce端的Common Join。
shuffle阶段
解决:减少每个reduce处理的数据量,调整参数:hive.exec.reducers.bytes.per.reducer,默认300000000。或调整放在内存里的最大片段所占百分比(set mapreduce.reduce.shuffle.memory.limit.percent=0.10)。
reduce阶段
解决:减少每个reduce处理的数据量,调整参数:hive.exec.reducers.bytes.per.reducer,默认300000000。如果存在数据倾斜,单纯增加reduce个数没有用,参考“Hive优化方法.ppt”进行数据倾斜优化。

2)执行动态分区HQL报错,报错信息类似如下:
org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error: Unable to deserialize reduce input key from x1x128x0x0x19x1x255 with properties {columns=reducesinkkey0,reducesinkkey1,reducesinkkey2,reducesinkkey3, serialization.lib=org.apache.hadoop.hive.serde2.binarysortable.BinarySortableSerDe, serialization.sort.order=++++++, columns.types=int,int,int,int,string,bigint}
解决:设置参数set hive.optimize.sort.dynamic.partition=false。

3)Hive创建文件数过多问题,报错信息类似如下:
total number of created files now is 100130, which exceeds 100000. Killing the job
解决:调大参数hive.exec.max.created.files。

4)Hive使用过多的变量替换,报错信息如下:
FAILED: IllegalStateException Variable substitution depth too large: 40
解决:调大参数hive.variable.substitute.depth。

5)select * 使用MR而不使用fetchtask
解决:set hive.fetch.task.conversion=minimal。

6)分区表分区字段是日期类型时限制分区条件使用to_unix_timestamp方法,如果使用unix_timestamp方法仍会扫全表。

7)Causedby:org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.hdfs.protocol.FSLimitException$PathComponentTooLongException): The maximum path component name limit of  ...Could not find status of job:job_id...这个问题是job name过长导致,一般任务运行成功,但看不到日志,historyserver提示任务not found。
解决:设置job 的名称set mapreduce.job.name=XXX;

8)使用动态分区时碰到如下报错信息:
Failed with exception Number of dynamic partitions created is 1191, which is more than 1000. To solve this try to set hive.exec.max.dynamic.partitions to at least 1191
参数hive.exec.max.dynamic.partitions限制了所允许的最大分区个数,默认值是1000。
解决:调大参数hive.exec.max.dynamic.partitions。

9)往rcfile格式的表insert数据时报“Caused by: java.lang.UnsupportedOperationException: Currently the writer can only accept BytesRefArrayWritable”
       解决:修改rcfile 表 serde 属性
       alter table table_name set serde 'org.apache.hadoop.hive.serde2.columnar.ColumnarSerDe';

10)任务执行报“Caused by: java.io.IOException: Split metadata size exceeded 10000000. Aborting job XXX”
       job.splitmetainfo文件大小超过默认值10000000(10M)。
       解决:调大参数mapreduce.jobtracker.split.metainfo.maxsize。

11)Hive执行报“FAILED: ParseException line ”
       解决:Hive语法问题,请检查自己的语句,如有不确定请查阅Hive语法。

12) Hive任务执行过程中失败,报“Caused by: java.io.FileNotFoundException: File does not exist: XXX”
       原因:任务运行过程中依赖的表发生了变化,可能是表被删了、表重建了或者表数据重新生成之类的等等情况。譬如,报错:“Caused by: java.io.FileNotFoundException: File does not exist: hdfs://XXX/user/A/hive/warehouse/A.db/trec_season2_coupon_info_pc/000000_0”,则是因为任务运行过程中,依赖的表A.trec_season2_coupon_info_pc发生了变化。

13)对于Hive里的分区表,新增字段后,通过insert overwrite等方式重新生成历史分区的数据,发现新增字段仍旧是null值。
        解决:Hive分区表新增字段后,需要对历史老分区进行重建才能查询新增字段,但是对于新增字段后新生成的分区是不受影响的,能正常查询数据。

14)FAILED: RuntimeException MetaException(message:java.lang.ClassNotFoundException Class org.openx.data.jsonserde.JsonSerDe not found)
        解决:确认是否对json-serde.jar执行了add jar。

15)Hive UDF参考:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF

16)FAILED: SemanticException [Error 10087]: The same output cannot be present multiple times
        原因:使用多重insert(multi insert)时,结果是非分区表则不能是同一个,分区表必须是不同分区,结果是hdfs目录的也必须不同。

17)任务运行正常,在最后move数据阶段报错:
Failed with exception Unable to move source XXX to destination XXX
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.MoveTask
        解决:set hive.exec.copyfile.maxsize=10000000000;

18)FAILED: SemanticException Line 0:-1 Invalid column reference '$f1'
解决:set hive.cbo.enable=false;

19)重复列名,报错关键字Ambiguous column reference * in *
       解决:去掉重复的字段
       示例:select t.id from (select dummy,dummy from default.dual)t;
                  FAILED: SemanticException [Error 10007]: Ambiguous column reference dummy in t
                  去掉子查询里的一个dummy字段。

20)union all的子句里不支持orderByClause、clusterByClause、distributeByClause、sortByClause或limitClause
        解决:改造hql,去掉union all子查询里的orderByClause、clusterByClause、distributeByClause、sortByClause和limitClause语句
        示例:select t.id from (select dummy from default.dual limit 1 union all select dummy from default.dual limit 1)t;

                   去掉两个子查询里的limit 1;

21)建表列名不允许包含.或:,报错如下:ParseException line 1:45 Failed to recognize predicate ')'. Failed rule: '[., :] can not be used in column name in create table statement.' in column specification
       解决:检查建表语句,将字段名中包含的.或: 去掉。

22)Cannot modify hive.conf.restricted.list at runtime. It is in the listof parameters that can't be modified at runtime
       原因:对hive.exec.max.dynamic.partitions,hive.exec.max.dynamic.partitions.pernode,hive.exec.max.created.files三个参数值进行了限制,用户自定义设置不生效,不影响任务的执行,除非动态创建的分区数和任务创建的文件数在任务运行过程中超过了限制值,任务才会失败。

23)interval 是hive-1.2版本里新增的关键字,不可作为表字段名、别名。
示例1:select dummy as interval from dual;  查询报错
NoViableAltException(142@[134:7: ( ( ( KW_AS )? identifier ) | ( KW_AS LPAREN identifier ( COMMA identifier )* RPAREN ) )?])
FAILED: ParseException line 1:16 cannot recognize input near 'as' 'interval' 'from' in selection target
示例2:create table test_interval(interval string);
NoViableAltException(142@[])
at org.apache.hadoop.hive.ql.parse.HiveParser_IdentifiersParser.identifier(HiveParser_IdentifiersParser.java:10858)
FAILED: ParseException line 1:27 cannot recognize input near 'interval' 'string' ')' in column specification

### Hive 常见面试问题及答案 #### 1. 请简单介绍下 Hive 架构? Hive 是一种建立在 Hadoop 上的数据仓库工具,其主要目的是让熟悉 SQL 的用户能够轻松查询存储在 HDFS 中的大规模数据集。Hive 提供了一个类似于 SQL 的查询语言——HiveQL (Hive Query Language),它可以被编译成 MapReduce 或 Tez 等任务来执行[^1]。 #### 2. Hive 表有哪些类型及其区别? Hive 支持多种类型的表,主要包括内部表(Managed Table)、外部表(External Table)、分区表(Partitioned Table)和分桶表(Buckets Table)。 - **内部表**:数据由 Hive 管理,删除表时数据也会随之删除。 - **外部表**:仅存储元数据信息,数据仍然存放在原始位置,删除表不会影响底层数据。 - **分区表**:按某些列进行划分以加速查询速度,适合大规模数据场景。 - **分桶表**:通过对指定列哈希取模实现均匀分布,进一步优化 Join 和采样操作。 #### 3. Hive 创建表有哪些方式? 可以通过 `CREATE TABLE` 语句创建表,支持如下几种形式: - 使用 DDL 定义结构并加载数据; - 从现有表中复制模式或数据; - 导入外部文件作为数据源[^1]。 #### 4. Hive 排序 Order By、Distribute By、Sort By 及 Cluster By 区别? - **Order By**:全局排序,默认会触发 Reduce 阶段,可能导致单点瓶颈。 - **Distribute By**:控制输入数据如何分配给 Reducer,通常用于分组前的操作。 - **Sort By**:针对每个独立的 Reducer 进行局部排序,不保证整体有序性。 - **Cluster By**:如果 Distribute By 和 Sort By 列相同,则可以用 Cluster By 替代两者[^1]。 #### 5. RANK、DENSE_RANK 及 ROW_NUMBER 的区别? 这三种窗口函数都用来为结果集中的每一行分配排名编号,但存在细微差异: - **RANK()**:允许跳跃重复值后的名次; - **DENSE_RANK()**:连续排列即使有相同的值也不会跳号; - **ROW_NUMBER()**:每条记录都会获得唯一标识符,即便数值相等也依次递增。 #### 6. Hive 中你使用过哪些内置函数? Hive 提供丰富的内置函数库,包括但不限于字符串处理函数 (`SUBSTR`, `CONCAT`)、日期时间转换函数 (`FROM_UNIXTIME`, `DATEDIFF`)、聚合统计函数 (`SUM`, `AVG`, `COUNT`) 等[^1]。 #### 7. Hive 中有哪些数据文件格式? 常见的文件格式有 TextFile、SequenceFile、RCFile、ORC、Parquet 等。其中 ORC 和 Parquet 属于列式存储格式,因其高效压缩率与读写性能,在大数据分析领域应用广泛[^2]。 #### 8. UDF、UDAF 及 UDTF 区别?是否有用过自定义函数? - **UDF(User Defined Function)**:单一返回值的标准函数; - **UDAF(User Defined Aggregation Function)**:聚集类运算如求平均数等功能扩展; - **UDTF(User Defined Table Generating Functions)**:将一条输入转化为多条输出记录的功能模块。 确实可以根据业务需求开发专属逻辑封装进以上三者之一加以运用。 --- ### 性能优化相关问题解答 #### 9. 如何通过分区来优化 Hive 查询性能? 合理设计 Partition Key 减少扫描范围至关重要。例如按照日期维度切分日志型海量数据集合可极大降低 I/O 成本从而加快响应速率[^2]。 #### 10. 如何使用桶(Bucket)来优化 Hive 性能? 设定 Bucket 数目依据 key 散列规则预先分割好子集便于后续快速定位目标片段参与计算过程进而达到提速效果[^2]。 #### 11. 什么是 Hive 的 Map Side Join? 如何启用它? 当小表可以全部载入内存时采用 map-side join 方案避免 shuffle 开销显著提升效率。设置参数 `hive.auto.convert.join=true` 自动识别适用情况开启此机制[^2]。 #### 12. 如何通过压缩提高 Hive 的存储和查询性能? 选用 Snappy/Gzip/LZO 等算法对中间产物实施编码缩减体积同时兼顾解码耗时平衡点达成双赢局面。 #### 13. 动态分区插入如何助力效能改进? 批量生成多个目录下的新批次资料免去逐一手工干预环节节省大量人力物力资源投入[^2]. --- ### 工作流与时长计算案例解析 #### 计算工作时长实例 假设需评估审批流程历时长短则可通过以下脚本实现: ```sql SELECT id, SUM(TIMESTAMPDIFF(HOUR, start_time, end_time)) AS total_hours FROM ( SELECT abc AS id, CASE WHEN status='申请' THEN timestamp END AS start_time, LEAD(CASE WHEN status='通过' THEN timestamp END IGNORE NULLS) OVER(PARTITION BY abc ORDER BY timestamp ASC) AS end_time FROM t14 WHERE status IN ('申请','通过') ) subquery GROUP BY id; ``` 这里借助窗口函数 `LEAD()` 获取相邻状态对应时间节点差额累加得出最终结论[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值