hive中join导致的数据倾斜问题排查, 分析热点值

本文详细分析了Hive中因大键导致的数据倾斜问题,包括任务卡住和超时等现象,并提供了通过时间判断、任务Counter检查等方法来识别倾斜。针对这种情况,提出了过滤脏数据、数据预处理、增加reduce个数、转换为MapJoin、大键单独处理和调整内存设置等解决方案。此外,还分享了如何找到倾斜的大键和对应SQL执行代码的方法。

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

https://blog.csdn.net/wisgood/article/details/77063606

 

hive中大key导致的join数据倾斜问题

1、场景
如果某个key下记录数远超其他key,在join或group的时候可能会导致某个reduce任务特别慢。本文分析下join的场景。
本例子SQL如下:查询每个appid打开的次数,需要排除掉作弊的imei。
selectappid,count(*)
from (
 select md5imei,appid
 from (
  select  t1.md5imei,t1.appid,t2.cheat_flags
  from  imei_open_app t1left outer joincheat_imei t2
  on t1.md5imei=t2.md5imei
 )t3
 where t3.cheat_flagsis null
) t4
group by appid ;

 
说明:表cheat_imei,7500万条,无大key,为作弊的imei。表imei_open_app,5亿6526万条,为每个imei打开的appid。该表中存在大key,md5imei=54bc0748b1c0fb46135d117b6d26885e的记录数有2亿3659万条。
2、Hadoop环境
hadoop 2.6.0-cdh5.8.0
hive-1.1.0-cdh5.8.0
3、导致的问题
可能会导致下面2个问题。
3.1 任务卡住
某个reduce task,卡在99.9%半天不动。如下
3.2 任务超时被杀掉。
Reduce task处理的数据量巨大,在做full gc的时候,stop the world。导致响应超时,超出默认的600秒,任务被杀掉。报错信息如下:

AttemptID:attempt_1498075186313_242232_r_000021_1 Timed outafter 600 secs Container killed by the ApplicationMaster. Container killed onrequest. Exit code is 143 Container exited with a non-zero exit code 143。

4、如何判断是大key导致的问题
可以通过下面方法。

4.1 通过时间判断
如果某个reduce的时间比其他reduce时间长的多。(注意:如果每个reduce执行时间差不多,都特别长,则可能是reduce设置过少导致的)。如下图。大部分task在4分钟之内完成,只有r_000021这个task在33分钟内还没完成。

 

另外注意,这里面需要排除一种特殊情况。有时候,某个task执行的节点可能有问题,导致任务跑的特别慢。这个时候,mapreduce的推测执行,会重启一个任务。如果新的任务在很短时间内能完成,通常则是由于task执行节点问题导致的个别task慢。如果推测执行后的task执行任务也特别慢,那更能说明该task可能会有倾斜问题。

4.2 通过任务Counter判断
Counter会记录整个job以及每个task的统计信息。counter的url一般类似:

http://rm:9099/proxy/application_1498075186313_242232/mapreduce/taskcounters/task_1498075186313_242232_r_000017  

1)通过输入记录数

普通的task counter如下,

而task=000021的counter如下,其输入记录数是2亿4000万。是其他任务的10几倍

2)通过输出字符数

普通的task counter如下,

而task=000021的counter如下,是其他任务的几十倍

5、如何找到大key及对应SQL执行代码
5.1 找到对应大key
一般情况下,hive在做join的时候,会打印join的日志。我们通过日志查找大key。

1) 找到任务特别慢的那个task,打开对应日志,url类似于

http://rm:8042/node/containerlogs/container_e115_1498075186313_242232_01_000416/hdp-ads-audit/syslog/?start=0

2)搜索日志中出现的“rows for joinkey”,如下图。

3)找到时间跨度最长的那条记录,如下图。比如[54bc0748b1c0fb46135d117b6d26885e],处理的时间从2017-08-03 11:31:30 一直到2017-08-03 11:46:35,耗时15分钟,任务依然没有结束。
。。。。。。由于日志过长,中间部分省略。。。。。。。
另外,从日志中也可能看到,54bc0748b1c0fb46135d117b6d26885e已经处理了236528000条数据,实际情况是该key在imei_open_app中有2亿3659万条数据。该key为导致join倾斜的key。
5.2 确定任务卡住的stage
1) 通过jobname确定stage

一般通过Hive的默认jobname会带上名称会带上stage阶段,如下为Stage-1。

2)如果jobname是自定义的,那可能没法通过jobname判断stage。需要借助于任务日志。找到执行特别慢的那个task,搜索 “CommonJoinOperator: JOIN struct” 。Hive在做join的时候,会把join的key打印到日志中,如下。

上图中的关键信息是struct<_col1:string,_col6:string>
这时候,需要参考该SQL的执行计划。通过参考执行计划,可以断定该阶段为stage1阶段。

5.3 确定SQL执行代码
确定了执行阶段(即stage),那么通过执行计划,就可以判断出是执行哪段代码时出现了倾斜。还是从上图,可以推测出是在执行下面红框中代码时出现了数据倾斜。

6、解决方案
6.1 过滤掉脏数据
如果大key是无意义的脏数据,直接过滤掉。本场景中大key无实际意义,为脏数据,直接过滤掉。

6.2 数据预处理
数据做一下预处理,尽量保证join的时候,同一个key对应的记录不要有太多。

6.3 增加reduce个数
如果数据中出现了多个大key,增加reduce个数,可以让这些大key落到同一个reduce的概率小很多。

6.4 转换为mapjoin
如果两个表join的时候,一个表为小表,可以用mapjoin做。

6.5 大key单独处理
将大key和其他key分开处理,SQL如下

 

select appid,count(*)
from (
 select md5imei,appid
 from (
    select md5imei,appid,cheat_flags
    from (  select  md5imei,appid,t2.cheat_flags from  imei_open_app  where md5imei="54bc0748b1c0fb46135d117b6d26885e" ) t1
    left outer join cheat_imei  t2
    on t1.md5imei=t2.md5imei
    union all 
    select md5imei,appid,cheat_flags
    from (  select  md5imei,appid,t2.cheat_flags from  imei_open_app  where md5imei!="54bc0748b1c0fb46135d117b6d26885e" ) t11
    left outer join cheat_imei  t12
   on t11.md5imei=t12.md5imei
 )t3
 where t3.cheat_flags is null
) t4
group by  appid  ;
6.6 hive.optimize.skewjoin
会将一个join SQL 分为两个job。另外可以同时设置下hive.skewjoin.key,默认为10000。参考:

https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties。但该

参数对full outer join无效。

6.7 调整内存设置
适用于那些由于内存超限内务被kill掉的场景。通过加大内存起码能让任务跑起来,不至于被杀掉。该参数不一定会降低任务执行时间。

如:

setmapreduce.reduce.memory.mb=5120 ;

setmapreduce.reduce.java.opts=-Xmx5000M  -XX:MaxPermSize=128m;

文章为作者原创文章,如果对您有帮助,欢迎打赏!![这里写图片描述](https://img-blog.csdn.net/2018040817584585)![这里写图片描述](https://img-blog.csdn.net/20180408180105136)
————————————————
版权声明:本文为CSDN博主「wisgood」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wisgood/article/details/77063606

### Hive 使用问题 Hive 是基于 Hadoop 构建的数据仓库工具,广泛用于大数据的批处理和分析。其使用过程中常见问题包括查询执行缓慢、元数据配置错误以及与 Hadoop 的集成问题等。 - 查询性能低下是 Hive 使用中最常见的问题之一。这通常与 SQL 语句编写方式、分区策略、文件格式选择等因素有关。 - 元数据配置错误可能导致 Hive 表无法访问或元数据丢失,影响任务正常运行。例如,Hive Metastore 配置不正确会导致连接失败[^3]。 - Hive 对接 Hadoop 时路径配置错误也可能导致任务失败,如 `hive-env.sh` 中未正确设置 Hadoop 安装路径[^3]。 ### Hive 配置问题 Hive 的性能和稳定性在很大程度上依赖于合理的配置设置。主要配置包括执行引擎、内存管理、并行执行等。 - 执行引擎可选择 MapReduce、Tez 或 Spark。其中 Tez 提供了更高效的 DAG 执行模型,适用于复杂查询场景[^4]。 - 内存配置方面,可通过 `hive.tez.container.size` 和 `hive.tez.java.opts` 设置容器大小和 JVM 堆内存,提升任务执行效率[^1]。 - 并行执行优化可通过 `hive.exec.parallel=true` 开启,允许多个阶段并发执行,减少整体执行时间[^1]。 此外,`.hiverc` 文件可用于设置默认参数,但会话级别的 `SET` 指令优先级更高[^5]。 ### Hive 错误处理 Hive 的错误类型多样,涉及语法错误、元数据异常、执行失败等多个层面。掌握其核心组件交互流程有助于快速定位问题: - **解析阶段**:SQL 语法错误会在该阶段被检测出。 - **获取元数据阶段**:表不存在、字段名错误等问题在此阶段暴露。 - **生成执行计划与优化阶段**:逻辑计划不合理(如未进行分区剪枝)会导致性能下降。 - **执行引擎(MR/Tez/Spark)阶段**:资源不足、数据倾斜问题可能引发任务失败[^4]。 对于错误排查,应结合 HiveServer2 日志、YARN 应用日志及 Hive Metastore 日志进行分析。 ### Hive 优化技巧 Hive 查询性能优化需从多个维度入手: #### SQL 优化 - **过滤条件前置**:将 WHERE 条件提前,减少中间结果集大小。 - **分区剪枝**:确保分区字段作为查询条件的一部分,避免全分区扫描。 - **合理使用 Join**:小表驱动大表(Map Join)、避免笛卡尔积、使用 Bucket Map Join 提升 Join 效率。 #### 配置优化 - **启用本地模式**:对于小数据集查询,可开启 `hive.exec.mode.local.auto=true`,避免启动分布式任务带来的开销。 - **压缩输出**:通过 `hive.exec.compress.output=true` 启用中间和最终输出压缩,节省 I/O 资源。 - **调整并行度**:根据集群资源设置 `hive.exec.parallel.threads` 控制并行任务数量[^5]。 #### 资源优化 - **执行引擎选择**:Tez 相较于 MapReduce 更适合复杂 DAG 任务,Spark 则更适合迭代计算。 - **动态分区**:使用 `hive.exec.dynamic.partition.mode=nonstrict` 支持动态插入分区,提高灵活性。 - **分桶与索引**:对高频查询字段建立分桶,可加速采样和 Join 操作;建立索引可加快特定查询速度。 #### 数据存储优化 - **列式存储格式**:使用 ORC、Parquet 等列式存储格式可显著提升查询效率,尤其在只读取部分字段时。 - **合并小文件**:过多小文件会增加 NameNode 压力,可通过 `hive.merge.mapfiles=true` 自动合并输出文件。 ```sql -- 示例:ORC 存储格式建表语句 CREATE TABLE sales ( order_id STRING, customer_id STRING, amount DOUBLE ) STORED AS ORC; ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值