hive-数据倾斜介绍

本文介绍了Hive在处理大数据时常见的数据倾斜问题及其解决方案。针对join key值倾斜、reduce数量不足、group by倾斜等问题,提供了具体配置参数调整及优化策略。

原文链接

hive在跑数据时经常会出现数据倾斜的情况,使的作业经常reduce完成在99%后一直卡住,最后的1%花了几个小时都没跑完,这种情况就很可能是数据倾斜的原因,解决方法要根据具体情况来选择具体的方案

1、join的key值发生倾斜,key值包含很多空值或是异常值

这种情况可以对异常值赋一个随机值来分散key

如:

selectuserid , name

fromuser_info a

join (

select  case  when userid  is  null  then  cast ( rand ( 47 )* 100000  as i nt )

elseuserid

fromuser_read_log

)b  on a . userid  = b . userid

通过rand函数将为null的值分散到不同的值上,在key值比较就能解决数据倾斜的问题

注:对于异常值如果不需要的话,最好是提前过滤掉,这样计算量可以大大减少

2、当key值都是有效值时,解决办法为设置以下几个参数

set hive.exec.reducers.bytes.per.reducer = 1000000000

也就是每个节点的reduce 默认是处理1G大小的数据,如果你的join 操作也产生了数据倾斜,那么你可以在hive 中设定

set hive.optimize.skewjoin = true;

set hive.skewjoin.key = skew_key_threshold (default = 100000)

hive 在运行的时候没有办法判断哪个key 会产生多大的倾斜,所以使用这个参数控制倾斜的阈值,如果超过这个值,新的值会发送给那些还没有达到的reduce, 一般可以设置成你

(处理的总记录数/reduce个数)的2-4倍都可以接受.

倾斜是经常会存在的,一般select 的层数超过2层,翻译成执行计划多于3个以上的mapreduce job 都很容易产生倾斜,建议每次运行比较复杂的sql 之前都可以设一下这个参数. 如果你不知道设置多少,可以就按官方默认的1个reduce 只处理1G 的算法,那么  skew_key_threshold  = 1G/平均行长. 或者默认直接设成250000000 (差不多算平均行长4个字节)

3、reduce数太少

set mapred.reduce.tasks=800;

默认是先设置hive.exec.reducers.bytes.per.reducer这个参数,设置了后hive会自动计算reduce的个数,因此两个参数一般不同时使用

4、对于group by 产生倾斜的问题

set hive.map.aggr=true (开启map端combiner); //在Map端做combiner,假如map各条数据基本上不一样, 聚合没什么意义,做combiner反而画蛇添足,hive里也考虑的比较周到通过参数hive.groupby.mapaggr.checkinterval = 100000 (默认)

hive.map.aggr.hash.min.reduction=0.5(默认)

两个参数的意思是:预先取100000条数据聚合,如果聚合后的条数/100000>0.5,则不再聚合

set hive.groupby.skewindata=true;// 决定  group by 操作是否支持倾斜的数据。注意:只能对单个字段聚合. 控制生成两个MR Job,第一个MR Job Map的输出结果随机分配到reduce做次预汇总,减少某些key值条数过多某些key条数过小造成的数据倾斜问题

5、小表与大表关联

此时,可以通过mapjoin来优化,

set hive.auto. convert . join  true ; //将小表刷入内存中  

set hive.mapjoin.smalltable.filesize = 2500000 ;//刷入内存表的大小(字节)

### 数据倾斜问题概述 数据倾斜是指在大数据处理过程中,某些特定的任务或节点分配到了过多的数据量或计算负载,而其他任务或节点则相对轻松。这种不平衡会显著影响整个系统的性能和效率[^3]。 #### 数据倾斜的原因 数据倾斜的主要原因可以归纳为以下几个方面: - **数据分布不均**:如果原始数据本身存在明显的偏态分布,则可能会导致部分Key对应大量的记录,而另一些Key对应的记录较少甚至为空。 - **业务场景特性**:例如,在日志分析中常见的IP地址字段可能集中于少量热门IP;或者电商交易订单里可能存在极少数商品ID占据了大部分销量情况下的统计操作都会引发严重的数据倾斜现象[^1]。 #### 解决方案分类 针对上述提到的各种类型的倾斜状况,可以从不同角度出发采取相应的措施来缓解这一难题: ##### 无损方式 对于那些无法简单丢弃却又能独立完成的小规模子集可以通过如下手段加以优化: - 对分布极度失衡的部分单独提取出来另行运算后再合并结果,这样既能保留全部有用信息又不会拖累整体进度. 具体实现时可先按指定维度分组计数找出异常值集合之后再针对性地实施特殊策略. ##### 有损方式 当允许一定程度上的精度损失时还可以考虑采用下面几种简化办法快速降低复杂度: - 排除极端样本点如零值项等明显干扰因素可以直接舍弃不予理会; 通过增加额外的哈希层使得原本高度聚集在一起的大块被打散重新分配到更多可用资源上去承担负荷从而达到平衡效果的目的. ```python from pyspark.sql import SparkSession # 创建Spark Session实例 spark = SparkSession.builder.appName("DataSkewSolution").getOrCreate() # 加载Hive表作为DataFrame对象 df = spark.table("your_hive_table") # 方法一:对key进行二次Hash以减少热点分区的压力 hashed_df = df.selectExpr("*", "ABS(HASH(key_column)) % num_partitions AS hash_key") repartitioned_df = hashed_df.repartition("hash_key") # 方法二:预聚合技术用于减轻下游Join过程中的负担 pre_aggregated_df = df.groupBy("join_key").agg({"value_column": "sum"}).alias("a") final_result = pre_aggregated_df.join(another_df.alias("b"), col("a.join_key") == col("b.id")) # 展示最终结果 final_result.show() ``` 以上代码片段展示了如何利用PySpark框架有效应对可能出现的数据倾斜挑战的一些基本思路和技术细节说明[^2]. ### 结论 综上所述,面对日益复杂的实际应用场景需求变化莫测所带来的各种潜在风险隐患,我们需要不断学习探索更加高效合理的算法模型设计原则以及灵活运用各类工具平台所提供的强大功能特性相结合才能更好地满足未来发展的新要求。 问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值