Hive优化----利用随机数避免数据倾斜

本文详细阐述了数据倾斜现象及其解决策略,重点介绍了如何使用随机函数来解决倾斜问题,并通过示例SQL操作展示了实现过程。通过调整SQL查询逻辑,有效地减少了查询时间,提高了数据处理效率。

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

生数据,通常的象是:

     任务进长时间维持在99%(或100%),看任务监面,发现只有少量(1个或几个)reduce子任未完成。

     看未完成的子任,可以看到本地写数据量累非常大,通常超10GB可以为发生数据斜。                   数据斜一般是由于代中的joingroup bydistinctkey分布不均致的,大量经验表明数据斜的原因是人的建表疏忽或业务可以避的。如果确认业务需要这样倾斜的逻辑.

 

  • join,使用map join,即在查询头添加map join hint,例如

select /*+MAPJOIN(b)*/ * from a join b on a.id =b.id

将会把join转换为mapjoin,且将b表作小表理。

  • group bydistinct,使用两次MR化,即定参数: hive.groupby.skewindata=true
  • 随机数解决数据倾斜

 

一、随机函数解决倾斜

 

原始sql:

insertoverwrite table t_aa_click_log partition (pt=’${yyyymmddhh}’)

selecta.*

from(select * from t_aa_click_log1

wherept=’${yyyymmddhh}’

)a

leftouter join

(select* from t_aa_pv_info_log

wherept=’${yyyymmddhh}’) b

ona.pvid=b.pvid;

 

发现大量时间花费在reduce99%~100%这最后一步上,约占总时长20分钟的一半,

用以下sql检查下数据分布:

select*

from(

selectpvid,count(1) cnt

fromt_aa_click_log1

wherept=’${yyyymmddhh}’

groupby pvid) t

orderby cnt desc

limit50;

 

发现pvid=’NA’的占比最高,有100多万,而其他最多的也只有几十条,证实数据倾斜。

 

利用随机函数,将pvid=’NA’的数据随机分布到不同的reduce中:

insertoverwrite table t_aa_click_log partition (pt=’${yyyymmddhh}’)

selecta.*

from(select * from t_aa_click_log1

wherept=’${yyyymmddhh}’

)a

leftouter join

(select* from t_aa_pv_info_log

wherept=’${yyyymmddhh}’) b

–如果pvid长度<=2,包含pvid=NA或-1 等多种异常值,即用随机函数叠加处理,因为异常值本来就关联不到,所以加上随机函数对结果没有影响

oncase when length(a.pvid)<=2 then concat(a.pvid,rand()) else a.pvid end =b.pvid;

 

问题解决。

### Hive 数据倾斜解决方案 #### 方法一:通过修改空值键解决数据倾斜 当无效 ID(如 `-99`、`''` 或 `null` 等)引发数据倾斜时,可以通过将这些空值的键转换为带有随机数的字符串来实现负载均衡。这种做法能够使原本集中在单一 reduce 上的任务被分配到多个 reduce 中执行[^1]。 ```sql SELECT CASE WHEN key IS NULL OR TRIM(key) = '' THEN CONCAT('random_', FLOOR(RAND() * 10)) ELSE key END AS new_key, value FROM table; ``` 这种方法的优点在于减少了 I/O 操作次数以及整体作业数量,从而提升了性能[^1]。 --- #### 方法二:针对 Count Distinct 的优化 在 ETL 过程中,Count Distinct 是常见的操作之一,但它也可能成为 Reduce 端数据倾斜的主要原因。为了避免这种情况的发生,在设计阶段就需要特别注意如何处理这类聚合查询[^2]。 一种有效的策略是利用 Bitmap 或 HyperLogLog 来近似计算唯一值的数量,而不是直接使用 Group By 和 Distinct 关键字: ```sql -- 使用 HLL 聚合函数替代 COUNT(DISTINCT col) SELECT APPROX_COUNT_DISTINCT(col) FROM table; ``` 这种方式不仅降低了资源消耗还提高了运行速度。 --- #### 方法三:Map Join 技术的应用 如果存在一个小表与大表之间的连接场景,则可以考虑采用 Map Join 方式代替普通的 Shuffle Join。具体来说就是借助注解语法告诉引擎加载较小的一方进入内存完成匹配过程[^3]。 示例如下所示: ```sql SELECT /*+ MAPJOIN(small_table) */ large_table.id, small_table.name FROM large_table LEFT JOIN small_table ON large_table.key = small_table.key; ``` 此技术的核心优势在于它绕过了标准 shuffle 流程所带来的额外开销,进而加快整个流程的速度并减少潜在的数据偏斜风险[^3]。 --- #### 方法四:动态分区调整 为了防止因某些特定条件而导致的部分 reducer 承担过多工作量的情况发生,可以在 SQL 层面增加额外逻辑以重新划分输入记录所属组别。例如按照日期字段或者地理位置信息来进行二次散列运算后再参与后续步骤。 ```sql DISTRIBUTE BY HASH_FUNCTION(column_name); SORT BY column_name ASC/DESC; ``` 这样做的好处是可以更均匀地分布待处理单元至各个 worker 当中去[^1]. --- ### 总结 综上所述,面对不同类型的 Hive 数据倾斜现象有不同的应对措施可供选择。对于由特殊值造成的不均等问题可通过变换其表现形式加以缓解;而对于统计类指令则需寻找更加高效的算法模型予以替换;至于涉及多方交互的情形之下,则要充分利用好现有工具集所提供的便捷选项——即 map-side joins 功能。最终目的是让系统能够在最短时间内得出准确的结果的同时保持良好的稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值