Hive关联时丢失数据问题和常用的Hive SQL参数设置

tez在join操作中遇到数据丢失问题(牵涉hive优化) 前言 相信很多人遇到过,将tez集成到hive,进行表join操作,比如3张表进行join,发现最后结果预期比较 ,少了一些。然后对每个子查询进行分析,发现往往每个子查询又没有任何数据丢失!而是到了join阶段,数据才出现部分丢失。下面我们对此进行展开叙述。 问题排查 首先,为了排查到底是哪里的情况。我们知道,tez对DAG运算做了很多优化,传统MR运行有区别。那么到底如何查呢。 首先为... 阅读详情

问题描述:
描述1:表A存在主键为1的数据行,表B也存在主键为1的数据行,表A left join 表B,取主键为1的数据行时,表B数据缺失。
描述2: 基于描述1,count(表B字段)数据时,计数行数不准确(主要表现为缺数据)

针对结果的发生,本文从以下方面分析原因及提供解决方案:

  • 右表没有匹配的数据
  • 关联键数据类型不匹配
  • 受count列null值影响
  • Hive版本问题,在某些版本中,左连可能导致右表为null
  • 数据倾斜

并在文末附属了Hive SQL常用参数设置的说明。

下面进行逐一分析

1. 右表没有匹配的数据

SQL基础,略。

2. 关联键数据类型不匹配

首先要确定一个问题,Hive会不会自动匹配两表类型?下面开始验证

2.1 首先在test_db中创建表A,语句如下:

CREATE TABLE test_db.table_A
(
    id        int comment '编号',
    id_string string comment '编号字符串',
    name      string comment '名称'
)
    ROW FORMAT DELIMITED
        FIELDS TERMINATED BY ','
        LINES TERMINATED BY '\n'
        NULL DEFINED AS ''
    STORED AS TEXTFILE
    TBLPROPERTIES ("serialization.null.format" = '');

覆盖写入新数据如下:

insert overwrite table test_db.table_A
values (1, '1', '张三'),
       (2, '2', '李四'),
       (3, '3', '王五');
select id, id_string, name from test_db.table_A;

table_a数据

2.2 首先在test_db中创建表B,语句如下:

CREATE TABLE test_db.table_B
(
    id        int comment '编号',
    id_string string comment '编号字符串',
    money     decimal(10, 2) comment '金钱'
)
    ROW FORMAT DELIMITED
        FIELDS TERMINATED BY ','
        LINES TERMINATED BY '\n'
        NULL DEFINED AS ''
    STORED AS TEXTFILE
    TBLPROPERTIES ("serialization.null.format" = '');

覆盖写入新数据如下:

insert overwrite table test_db.table_B
values (1, '1', 10.1),
       (2, '2', 20.1),
       (2, '2', 20.2),
       (3, '3', 30.1),
       (3, '3', 30.2),
       (3, '3', null);
select id, id_string, money from test_db.table_B;

table_b数据

2.3 接下来使用int类型的table_a.id关联string类型的table_b.id_string

select a.id, b.id_string, a.name, b.money
from test_db.table_a a
left join test_db.table_b b on a.id = b.id_string

得到结果如下:
ab表关联

可见,Hive不会因类型而关联异常。一般来讲,同一个含义的列在不同表中应保持列名和类型相同。

3. 受count列null值影响

在Hive Sql中,count()方法的使用及相关区别如下:

select count(*) from test_db.table_b;
-- 输出结果:6
select count(1) from test_db.table_b;
-- 输出结果:6
select count(money) from test_db.table_b;
-- 输出结果:5
select count(distinct money) from test_db.table_b;
-- 输出结果:5
select count(distinct coalesce(money, 1)) from test_db.table_b;
-- 输出结果:6

可见,count(column)将自动排除null值数据行

4. Hive版本问题,在某些版本中,左连可能导致右表为null

这里直接照搬文档如下:

在Hive 0.13.0和Hive 0.14.0版本中,这两个版本的Hive引擎使用了新的Cost-Based Optimizer(CBO)作为查询优化器。
CBO主要是通过对数据分布和数据统计信息进行分析,来选择最优的查询计划。
但是,在左连接的情况下,CBO对于一些特殊情况下的数据分布和统计信息计算出的结果可能存在误差,从而导致左连接时未能正确关联上数据。

从Hive 0.15.0版本开始,Hive引擎将默认使用新的Rule-Based Optimizer(RBO),而不再使用CBO,因此该问题已经得到了解决。
同时,在Hive 0.13.0和0.14.0版本中,可以通过设置hive.cbo.enable参数为false,禁用CBO,从而规避这个问题。

5. 数据倾斜

关联中的数据倾斜通常是由于大小表关联,可能某个Reducer处理数据量与其他差异过大导致
我们可以通过查询前临时设置来解决这个问题,下面介绍几个常用设置:

  • set hive.merge.smallfiles.avgsize=[数值];: 这个指令参数用于指定需要合并的小文件的平均大小,单位是字节。
    默认值是 16 MB。当输入数据被分割成多个小文件时,如果这些小文件总大小超过了这个阈值,Hive会自动合并这些小文件。
    这样可以减少Mapper的数量,提高作业的并发度,从而更好地处理数据倾斜的情况。
  • set hive.exec.reducers.bytes.per.reducer=[数值];: 这个参数用于指定每个 Reducer 处理的数据量大小,单位是字节。
    这个数值过大、过小都不合适,需要预估查询从而设置更合适的范围。
    并且,如果发生了本文中提到的关联丢失数据,我建议仅使用这条参数即可解决,根据查询大小,尝试增加或减少此数值,尽可能平衡每个reducer的处理即可!
  • set mapred.max.split.size=[数值]:这个参数用于指定 Map 任务处理的输入数据的最大分片大小,单位是字节,默认值是 1GB。
    默认值是 64MB。如果该参数设置得太小,可能会导致数据分片过多,从而增加了任务调度的开销,降低了并发度,也可能造成数据倾斜。
    如果设置得太大,又会导致单个 Map 任务处理的数据量过大,从而增加了单个任务的执行时间。因此,需要根据实际情况进行调整,使 Map 任务处理的数据量适中,以达到最佳的性能。

总结

几个方面分析完成以后,可以发现基本是数据倾斜导致的关联数据缺失,我建议参考上方所说的在执行特殊查询前加上set hive.exec.reducers.bytes.per.reducer=[数值];
尝试解决。需注意的是,请查看原本该值设定是多少,然后根据你的查询去决定数值为多少

附文:常用的Hive SQL参数设置及解释

  1. set hive.exec.parallel=true;: 默认值为false,开启Hive执行任务的并行化,这样Hive可以在多个处理器上同时执行不同的任务,提高作业的执行速度。
  2. set mapreduce.job.queuename=hadoop;: 默认值为"default",指定MapReduce作业提交到的队列名称,当Hadoop集群中有多个队列时,可以通过此参数指定作业提交的队列。
  3. set hive.exec.dynamic.partition=true;: 默认值为false,开启Hive动态分区功能,这样可以在插入数据时动态创建分区,而不是需要提前手动创建好分区。
  4. set hive.exec.dynamic.partition.mode=nostrict;: 默认值为"strict",设置动态分区模式为非严格模式,即在插入数据时,只需要指定要插入的分区字段即可,不需要指定所有的分区字段。
  5. set hive.exec.max.dynamic.partitions=10000;: 默认值为1000,设置动态分区最大数量为10000个,即在动态分区时,最多只能创建10000个分区。
  6. SET hive.exec.max.dynamic.partitions.pernode=10000;: 默认值为100,设置每个节点上动态分区最大数量为10000个,即每个节点最多只能创建10000个分区。
  7. set mapred.map.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;: 默认值为null,设置Map任务输出时采用Gzip压缩算法进行压缩,减小数据的磁盘占用。
  8. set hive.exec.compress.intermediate=true;: 默认值为false,开启Hive中间结果的压缩,可以减小数据在磁盘上的占用。
  9. set mapred.output.compression.type=BLOCK;: 默认值为NONE,可选的值为NONE、BLOCK、RECORD。设置输出数据的压缩格式为块压缩(Block Compression),这种压缩方式可以提高压缩率。
  10. set hive.exec.compress.output=true;: 默认值为false,开启输出结果的压缩,减小数据在磁盘上的占用。
  11. set hive.merge.smallfiles.avgsize=120000000;: 默认值为256MB,当小文件个数超过一定阈值时,Hive会自动将它们合并成一个大文件。这里设置合并后的文件大小为120MB。
  12. set hive.exec.reducers.bytes.per.reducer=10000000;: 默认值为1GB,设置每个Reducer处理的数据量大小,这里设置为10MB。
  13. set mapred.max.split.size=100000000;: 默认值为64MB,设置每个输入Split的最大大小为100MB,这样可以控制每个Map任务处理的数据量,避免数据倾斜。
  14. set hive.merge.mapfiles=true;: 默认值为false,开启小文件合并,将多个小文件合并成一个大文件。
  15. set hive.merge.mapredfiles=true;: 默认值为false,开启Map任务输出结果的小文件合并功能,可以将多个Map任务输出的小文件合并成一个大文件。
HIVE 3 使用 MR 引擎多表关联 (JOIN) 导致丢数的问题复现、问题根源及解决方案 (附代码) 阅读详情

相关推荐

Hive数据倾斜的原因以及常用解决方案

Hive数据倾斜的原因以及常用解决方案

日常分享数据分析开发、编程语言内容 6994

记一次mr中途落盘数据丢失 hdfs超租约异常 Error: java.io.FileNotFoundException: File does not exist:

这种问题首先定位的是hdfshadoop基础环境的问题,因为不是稳定发生,概率也不确定,所以非常不好复现,但却关键刻会发生给你一记背刺,最关键的是失败了他会判定为成功,你就算监控都监控不到,就很让人麻。将DataNode max data transfer threads 参数从16401 翻倍 解决问题。现象为:mr任务偶尔中途失败,但执行结果yarn会判定为成功,具体可以看日志报错。

Direction_Wind的博客 1350

Hive多表关联过滤条件中按in的子查询进行过滤

Hive多表关联过滤条件中按in的子查询进行过滤

编程技术、独立开发、技术资讯以及编程感悟等内容 923

哪些情况会导致hive表丢数据

spark hive

yy的博客 764

hive3 union数据

hive3 union数据

胖胖的博客 1040

sql关联数据异常看精度丢失问题

目录 背景 代码测试: 测试结果: 结果说明: 原因分析: float与double的范围精度 解决方案: 背景 bigintstring做join的候 会先都隐式转换成double在join,可能会由于精度丢失导致join的结果不符合预期,导致sql不符合预期 代码测试: set hive.mapred.mode=nonstrict; select 90000...

resemble的博客 1255

关于hive3多表leftjoin导致数据丢失问题及解决方案

关于hive3多表leftjoin导致数据丢失问题及解决方案

weixin_44203240的博客 3940

Hive 数据倾斜 常用解决办法

来源:https://www.cnblogs.com/qingyunzong/p/8847597.html 1.数据倾斜的原因 数据分布不均匀,造成数据热点问题 2.数据倾斜的现象 Hive任务进度长间维持在99%或者100%的附近,进度好久没变化。通过查看任务监控页面Web,发现只有一个或者少数的reduce任务未完成,因为其处理的数据其他的reduce差异过大。单一reduce处理的记录数平均记录数相差过多,导致最长间远大于任务的平均长。 3.数据倾斜情况...

是个好男人的博客 3921

Hive中LEFT OUTER JOININNER JOIN连用数据缺失问题

JOIN连接是SQL常用关联方式,但他们之前连用可能会出现数据缺失的情况,本文分享生产中的bug案例,目前已有解决方案,但具体原因未知,求各位小伙伴解答。

zhangliushi的博客 3168

hive优化总结

优化,把hive sql当做map reduce程序来读,会有意想不到的惊喜。 理解hadoop的核心能力,是hive优化的根本。这是这一年来,项目组所有成员宝贵的经验总结。   长期观察hadoop处理数据的过程,有几个显著的特征: 1.不怕数据多,就怕数据倾斜。 2.对jobs数比较多的作业运行效率相对比较低,比如即使有几百行的表,如果多次关联多次汇总,产生十几

上帝之手 3万+

Spark SQL实现Hive表与Kafka流数据联合分析实战

/ 从Hive读取维度表 val userDimDF = spark . sql("""SELECTuser_id,user_name,age,gender,city_id,is_vip""") // 读取订单事实表(用于流批Join) val orderFactDF = spark . sql("""SELECTorder_id,user_id,dtWHERE dt >= date_sub(current_date(), 7) -- 最近7天数据

✨ 欢迎来到【Seal ^_^ 的CSDN博客】!✨ 2423

hive解决数据倾斜问题_Hive数据倾斜解决办法

转自:https://blog.csdn.net/xinzhi8/article/details/71455883操作:关键词情形后果Join其中一个表较小,但是key集中分发到某一个或几个Reduce 上的数据远高于平均值大表与大表,但是分桶的判断字段0值或空值过多这些空值都由一个reduce处理非常慢group bygroup by 维度过小,某值的数量过多处理某值的reduce非常耗Cou...

weixin_36209301的博客 1179

数据仓库,Hive中使用 不等于 符号进行条件过滤的坑

最近在建设数据仓库,处理数据的过程中,经常反复使用hive的HQL语句,尽管HQLSQL语言有很多相同之处,但也并不是说HQL就能通用SQL的语法。在使用过程中要尤为注意。事情经过是这样的,我在把业务系统数据同步到数仓(数据存储在Hive)中,在数据汇总层(DWS),对数据进行汇总处理,发现有数据丢失问题,经过排查,发现是在使用 <> 引发的坑。 Hive 中 != 或 <> 致命陷阱 业务场景:把业务数据抽到ODS层(原始数据层)、在DWS层(数据汇总层),对多张多.

hechaoyong12345的博客 2526

hive--Hive数据倾斜的原因解决方法

来源:https://yq.aliyun.com/articles/60908 数据倾斜 在做Shuffle阶段的优化过程中,遇到了数据倾斜的问题,造成了对一些情况下优化效果不明显。主要是因为在Job完成后的所得到的Counters是整个Job的总,优化是基于这些Counters得出的平均值,而由于数据倾斜的原因造成map处理数据量的差异过大,使得这些平均值能代表的价值降低。

智慧与美貌并存 1万+

hive数据倾斜

hive数据倾斜:基本可以理解为hive在处理数据候,由于数据分布不均匀导致处理数据处理间过长。 注释:想要详细了解的朋友建议先去看看mapreduce的运行原理 hive在处理数据候,map端将hdfs上数据处理完会以<k ,v>的格式传给reduce端,由于可能某一部分的k值可能特别的多,某些特别少,导致某一部分reduce处理数据间特别长,从而产生数据倾斜。 1数据倾斜的...

cysgdsg的博客 253

hive 字符串转数字_15、Hive数据倾斜与解决方案

数据倾斜1、什么是数据倾斜由于数据分布不均匀,造成数据大量的集中到一点,造成数据热点2、数据倾斜的现象在执行任务的候,任务进度长间维持在99%左右,查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。因为其处理的数据其他reduce差异过大。 单一reduce的记录数与平均记录数差异过大,通常可能达到3倍甚至更多。最长长远大于平均长。3、数据倾斜的情况4、数据倾斜的...

weixin_36250220的博客 3144

解决hive数据倾斜问题

  平常工作中我们在使用hive处理业务问题候不可避免的会遇到数据倾斜的问题数据倾斜的本质就是key的分布不均匀,导致分到不同reduce上的数据量差距或大或小,当数据量差距过大的候就造成了数据倾斜,使得某一个reduce的负担过大,导致任务迟迟不能完成。 主要原因 1.key分布不均匀。 2. map端数据倾斜,输入文件过多,并且大小不统一。 3. reduce端数据倾斜,分区器存在问题。 4.业务数据本身特征。 解决方案 1.调节hive中的参数 如下所示: set hive.map.aggr=

AnameJL的博客 971
上一篇: 每一个人都应该明白的ChatGPT所带来的意义
下一篇: Java基本数据类型与对应的包装类
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值