Hive使用TEZ执行count(*)结果不正确

本文探讨了在使用Hive时遇到的一个常见问题:通过TEZ执行引擎进行count(*)操作时,返回的结果与实际记录数不符。文章详细解释了原因,并提供了解决方案——通过运行ANALYZE TABLE命令更新表统计信息。

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

现象

Hive使用TEZ作为默认的执行引擎,当表插入完记录后,count()得到的结果与实际的记录数不一致,如果使用MR作为执行引擎来执行count(),结果与实际记录数一致。

解决

使用TEZ执行count()十分高效,绕过了MapReduce操作,实际结果不正确,应该是TEZ内部有某种机制count()直接查询统计信息,然后统计信息不是最新的,导致count(*)结果不正确。

hive> select count(*) from test1;
OK
1131921

查看表结构,我们发现count(*)的记录数与表结构中的numRows保持一致,

hive> show create table test1;
OK
CREATE TABLE `test1`(
  `pripid` string, 
  `uniscid` string, 
  `entname` string, 
  ...)
ROW FORMAT DELIMITED 
  FIELDS TERMINATED BY '\u0001' 
  LINES TERMINATED BY '\n' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
  'hdfs://hadoop1/apps/hive/warehouse/default.db/test1'
TBLPROPERTIES (
  'COLUMN_STATS_ACCURATE'='true', 
  'numFiles'='28', 
  'numRows'='1131921', 
  'rawDataSize'='685459303', 
  'totalSize'='2323131590', 
  'transient_lastDdlTime'='1531319725')
Time taken: 0.227 seconds, Fetched: 48 row(s)

使用ANALYZE命令对表重新更新统计信息并重新统计后结果正确,

hive> analyze table test1 compute statistics;
Query ID = trafodion_20180711104240_02eb6fb5-f53c-454f-aa1e-8c6ca157b21c
Total jobs = 1
Launching Job 1 out of 1


Status: Running (Executing on YARN cluster with App id application_1531148517927_2403)

--------------------------------------------------------------------------------
        VERTICES      STATUS  TOTAL  COMPLETED  RUNNING  PENDING  FAILED  KILLED
--------------------------------------------------------------------------------
Map 1 ..........   SUCCEEDED    146        146        0        0       0       0
--------------------------------------------------------------------------------
VERTICES: 01/01  [==========================>>] 100%  ELAPSED TIME: 12.62 s    
--------------------------------------------------------------------------------
Table test1 stats: [numFiles=28, numRows=5562243, totalSize=2323131590, rawDataSize=2317569347]
OK
Time taken: 14.247 seconds
hive> select count(*) from test1;
OK
5562243
Time taken: 0.045 seconds, Fetched: 1 row(s)
<think>我们正在处理HiveonTez中由于数据倾斜导致的groupby操作性能问题,特别是任务无法完成的情况。结合引用内容,我们将重点讨论如何利用Tez的倾斜优化特性以及相关配置。根据引用[1]和[2]:-引用[1]提到可以通过调整tez.grouping.max-size参数来增加Map任务数量,从而提升并行性。-引用[2]详细介绍了Hive中处理数据倾斜的两种主要策略:将groupby分成两个MR阶段(在Tez中对应两个DAG阶段)以及在Map端进行部分聚合。针对倾斜groupby优化,Tez提供了自动处理倾斜的配置参数。同时,我们也可以手动进行热点key分散。解决方案如下:1.**启用Tez的自动倾斜处理**(推荐首先尝试):```sql--开启groupby倾斜优化SEThive.tez.groupby.skewed=true;--设置倾斜key的阈值(当某个key的记录数超过该值则视为倾斜)SEThive.groupby.skewindata=true;--这个参数在MR引擎中常用,在Tez中通常使用hive.tez.groupby.skewedSEThive.skewjoin.key=100000;--默认值100000,可根据数据量调整```2.**手动分散热点key**(当自动优化效果足时):引用[2]中提到的方法:将groupby拆分成两个阶段。在Tez中,我们可以通过子查询手动实现:```sqlSELECTkey,SUM(partial_sum)AStotal_sumFROM(SELECTkey,--第一阶段:在map端进行部分聚合SUM(value)ASpartial_sumFROMsource_tableGROUPBYkey)stage1GROUPBYkey;```或者对热点key添加随机后缀分散到多个reduce:```sqlSELECTbase_key,SUM(value)AStotal_sumFROM(SELECT--对热点key添加随机后缀(假设我们已知热点key是'hotkey')CASEWHENkey='hotkey'THENCONCAT(key,'_',CAST(CEIL(RAND()*10)ASSTRING))ELSEkeyENDASbase_key,valueFROMsource_table)tempGROUPBYbase_key;```3.**调整并行度参数**(引用[1]):```sql--增加Map任务数量(减小max-size会使得每个Map处理的数据量变小,从而增加Map数量)SETtez.grouping.max-size=104857600;--100MB(默认是1GB)--调整Reduce任务数量SEThive.exec.reducers.bytes.per.reducer=67108864;--64MB/Reducer(默认256MB)```4.**启用Map端聚合**(引用[2]):```sqlSEThive.map.aggr=true;--默认已开启,确保开启SEThive.groupby.mapaggr.checkinterval=100000;--Map端聚合的行数检查间隔```5.**资源调优**(防止单个Reduce因内存足而失败):```sql--增加Reduce任务内存SETtez.task.resource.memory.mb=8192;--调整JVM堆大小SEThive.tez.java.opts=-Xmx6144m;```6.**监控与诊断**:-使用TezUI(引用[3]中提到的JobName可通过配置自定义,但默认即可)查看任务进度,特别关注每个Reduce处理的数据量。-检查日志中是否有内存溢出(ContainerkilledbyYARN)或GC过度的信息。如果上述方法仍能解决问题,可能需要分析数据分布(使用引用[2]中的分布检查查询)并针对性优化。相关问题:1.如何通过TezUI准确定位数据倾斜的Reduce任务?2.HiveonTez中如何平衡Map任务数量和资源利用率?3.除了随机后缀,还有哪些手动处理数据倾斜的技巧?</think>### Hive Tez Group By Skewed Optimization 问题解决方案 针对 Tez 引擎中 `GROUP BY` 数据倾斜导致的任务无法完成问题,结合引用内容的核心优化策略,提供以下解决方案: --- #### 一、核心优化策略(基于引用[1][2]) 1. **启用Tez自动倾斜处理** ```sql -- 开启分组倾斜优化 SET hive.tez.groupby.skewed=true; -- 设置倾斜阈值(默认10万) SET hive.skewjoin.key=500000; ``` **原理**:Tez自动检测倾斜Key,将大Key拆分成多个子任务并行处理[^2]。 2. **两阶段聚合优化** ```sql -- 第一阶段:Map端预聚合 SET hive.map.aggr=true; -- 第二阶段:Reduce端最终聚合(引用[2]策略) SET hive.groupby.skewindata=true; ``` **效果**:通过预聚合减少传输数据量,分散Reduce负载[^2]。 3. **动态调整并行度** ```sql -- 减小分组大小提升并行度(引用[1]) SET tez.grouping.max-size=104857600; -- 100MB -- 控制Reduce数量 SET hive.exec.reducers.bytes.per.reducer=134217728; -- 128MB/Reducer ``` **优势**:将任务从2个并发扩展到15+,显著提升并行性能[^1]。 --- #### 二、高级调优技巧 1. **热点Key手动分散** ```sql SELECT CASE WHEN key = '热点值' THEN CONCAT(key, '_', FLOOR(RAND()*10)) ELSE key END AS skewed_key, SUM(value) FROM table GROUP BY skewed_key; ``` **适用场景**:已知明确热点Key(如NULL或特定枚举值)。 2. **内存资源优化** ```sql -- 防止Reduce OOM(基于倾斜数据量) SET tez.task.resource.memory.mb=12288; -- 12GB SET hive.tez.java.opts=-Xmx8192m; ``` 3. **启用CBO优化器** ```sql SET hive.cbo.enable=true; ANALYZE TABLE table COMPUTE STATISTICS FOR COLUMNS key; -- 收集统计信息 ``` --- #### 三、监控与验证 1. **在Tez UI定位倾斜任务** - 访问 `http://<resourcemanager>:8088/tez-ui` - 检查Vertex中各Task的 `Records/Size` 差异 >50%即存在倾斜 2. **倾斜Key分析** ```sql -- 识别Top热点Key SELECT key, COUNT(*) cnt FROM table GROUP BY key ORDER BY cnt DESC LIMIT 10; ``` 3. **效果验证指标** - Reduce任务完成时间标准差 < 30% - GC时间占比 < 10% - 再出现单个Task运行超时 > **案例**:某日志分析任务优化后效果: > ```diff > - 原状态:1个Reduce卡住2小时 > + 优化后:15个Reduce在8分钟内完成 > ``` > 关键配置: > ```sql > SET hive.tez.groupby.skewed=true; > SET tez.grouping.max-size=100000000; > ``` --- #### 四、常见失败场景处理 | 现象 | 解决方案 | |---------------------|---------------------------------| | `Container killed` | 增加 `tez.task.resource.memory.mb` | | GC overhead | 提升 `hive.tez.java.opts` 值 | | 数据本地性丢失 | 检查HDFS块分布,启用 `tez.locality.delay` |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据源的港湾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值