Hive中 join导致的数据倾斜问题及解决方案

news/2025/2/26 13:15:38/文章来源:https://www.cnblogs.com/wy56297/p/18738248

一、Hive中 join操作是如何完成的?

在Hive中,Join操作是通过MapReduce框架来实现的。假设现在users表与orders表用user_id字段进行连接操作,SQL语句如下:

SELECT u.user_id, u.username, o.order_id, o.amount
FROM users u
JOIN orders o ON u.user_id = o.user_id;

Map阶段

users表的Map输出

  • 键(Key)user_id
  • 值(Value)<username, registration_date>(假设users表中有usernameregistration_date字段)

例如:

  • (user_1, ("Alice", "2020-01-01"))
  • (user_2, ("Bob", "2020-02-01"))
  • (user_3, ("Charlie", "2020-03-01"))

orders表的Map输出

  • 键(Key)user_id
  • 值(Value)<order_id, amount>(假设orders表中有order_idamount字段)

例如:

  • (user_1, (order_1, 100))
  • (user_1, (order_2, 200))
  • (user_2, (order_3, 150))
  • (user_3, (order_4, 300))

Shuffle和Sort阶段

在Shuffle和Sort阶段,中间键值对会根据user_id进行分区和排序。例如:

  • user_1的所有记录会被发送到同一个Reducer节点:

    • (user_1, ("Alice", "2020-01-01"))
    • (user_1, (order_1, 100))
    • (user_1, (order_2, 200))
  • user_2的所有记录会被发送到另一个Reducer节点:

    • (user_2, ("Bob", "2020-02-01"))
    • (user_2, (order_3, 150))
  • user_3的所有记录会被发送到另一个Reducer节点:

    • (user_3, ("Charlie", "2020-03-01"))
    • (user_3, (order_4, 300))

Reduce阶段

在Reduce阶段,Reducer任务会处理具有相同user_id的记录,并执行Join操作。例如:

  • 对于user_1

    • 输入:
      • (user_1, ("Alice", "2020-01-01"))
      • (user_1, (order_1, 100))
      • (user_1, (order_2, 200))
    • 输出:
      • (user_1, "Alice", "2020-01-01", order_1, 100)
      • (user_1, "Alice", "2020-01-01", order_2, 200)
  • 对于user_2

    • 输入:
      • (user_2, ("Bob", "2020-02-01"))
      • (user_2, (order_3, 150))
    • 输出:
      • (user_2, "Bob", "2020-02-01", order_3, 150)
  • 对于user_3

    • 输入:
      • (user_3, ("Charlie", "2020-03-01"))
      • (user_3, (order_4, 300))
    • 输出:
      • (user_3, "Charlie", "2020-03-01", order_4, 300)

二、问题是如何产生的?

上述执行join操作的过程中,如果某些用户的订单记录非常多,那么处理这些用户的Reducer节点负载会非常高,而处理其他用户的Reducer节点负载则很低。这种数据分布不均的情况就是Hive中join操作的数据倾斜问题。产生数据倾斜问题的原因如下:

  • 数据分布不均:某些Key在业务场景中天然存在大量数据(如热门商品、活跃用户)。
  • 数据质量问题:存在大量空值或默认值(如NULL0),导致这些Key被集中处理。
  • 业务逻辑特性:例如,测试用户(如user_A)的订单数据被高频插入,形成大Key。

三、如何解决?

  1. 数据预处理
    • 过滤异常值:提前过滤掉空值或异常值。
    • 拆分大key:将大key拆分为多个小key。
  2. 优化SQL
    • Map Join:对小表使用Map Join,避免Shuffle阶段。
    • 倾斜key单独处理:将倾斜key单独处理后再合并结果。
  3. 调整参数
    • 增加Reducer数量:通过hive.exec.reducers.bytes.per.reducer调整。
    • 启用倾斜优化:设置hive.optimize.skewjointrue
  4. 使用随机数
    • 添加随机前缀:对大key添加随机前缀,分散数据。

四、案例分析

问题产生

假设有两张表:

  • 用户表(users):100万用户,用户ID均匀分布。
  • 订单表(orders):1亿条订单,其中用户A(测试用户)有5000万条,用户B有3000万条,其余用户订单较少。

执行以下Join操作时,用户A和B的订单集中在少数Reducer,导致任务卡顿。

解决方案

(1) 过滤异常用户

直接消除倾斜源,但会丢失用户A和B的数据。

-- 直接过滤测试用户A和B的订单
WITH filtered_orders AS (SELECT * FROM orders WHERE user_id NOT IN ('user_A', 'user_B')
)
SELECT u.user_id, u.username, o.order_id, o.amount
FROM users u
JOIN filtered_orders o ON u.user_id = o.user_id;

(2) 拆分大用户

将用户A和B的订单分散到10个子Key(user_A_0user_A_9),每个Reducer处理约500万条用户A数据和300万条用户B数据,负载均衡。

-- 为用户A和B的订单添加随机后缀(如user_A_0, user_A_1)
WITH split_orders AS (SELECT user_id,order_id,amount,CASE WHEN user_id IN ('user_A', 'user_B') THEN CONCAT(user_id, '_', CAST(FLOOR(RAND() * 10) AS STRING))ELSE user_idEND AS new_user_idFROM orders
)
SELECT u.user_id, u.username, o.order_id, o.amount
FROM users u
JOIN split_orders o ON u.user_id = o.new_user_id;

(3) 使用map join

在Map阶段直接处理大表(如订单表)的每个分片,本地匹配内存中的小表数据,无需按Key分发数据。

-- 启用MapJoin并调整小表阈值
SET hive.auto.convert.join=true;             -- 自动转换MapJoin
SET hive.mapjoin.smalltable.filesize=250000000;  -- 设置小表阈值(例如250MB)-- 强制使用MapJoin关联用户表和订单表
SELECT /*+ MAPJOIN(u) */ u.user_id, u.username, o.order_id, o.amount
FROM users u
JOIN orders o ON u.user_id = o.user_id;

(4) 参数调优(辅助手段)

通过调整参数,Hive自动对倾斜Key进行优化处理。

-- 增加Reducer数量并启用倾斜优化
SET hive.exec.reducers.bytes.per.reducer=256000000;  -- 每个Reducer处理256MB数据
SET hive.optimize.skewjoin=true;                   -- 启用倾斜优化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/890074.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[c++算法] 树的直径,包教包会!

哈喽大家好,我是 doooge。今天我们要将数论中的一个算法-树的直径。 $$\Huge 树的直径 详解$$ 1.树的直径是什么 这是一棵图论中的树:这棵树的直径就是这棵树中最长的一条简单路径。 2.树的直径怎么求 2.1暴力算法 直接对每个点进行 DFS,找到每个点离最远的点的距离,最后求…

图吧工具箱PC电脑工具(图拉丁吧硬件检测工具箱) v2025.01 中文绿色便携版

点击上方蓝字关注我 前言 图吧工具箱(大家通常叫它图拉丁吧硬件检测工具箱)是一个完全免费、开源、没有广告的硬件检测工具集合。这个工具箱是专门为喜欢自己动手组装电脑(DIY)的朋友们,特别是图钉社区的成员们制作的。里面包含了好多常用的硬件测试和检测小工具,特别适合…

在Windows上安装UOS打印机

因自己放在办公室发挥余热的Windows电脑即将寿终正寝,所以这两天试着将包括文件打印在内的基础网络服务逐渐转移到UOS主机上。 参照官方教程一通操作,Windows始终在添加打印机页面找不到同个局域网下的UOS主机,点击疑难解答则提示“该设备或资源未设置为接受端口“文件和打印…

是不是长大之后便很难再专注了?

写在前面 1100 字 | 专注 | 思考 | 逆向思维 正文“上课要专心。”我们似乎总能听见大人们这样要求我们。不过坦白地说,我真正体验过全神贯注的时刻,就那么一两次。看起来这篇文章,似乎又要大吐苦水,谈论生活怎样艰辛困苦,各种科技产品怎样将人碎片化之类。并不是。 恰恰相…

2025牛客寒假算法基础集训营3补题笔记

比赛链接 题目难度顺序大致为:\(A、M、F、L、C、\) \(easy\):\(A、M、F、L、C\) 太难了这场。。。E题卡了3个多小时。。。 A.智乃的博弈游戏 题意 有\(n\) 个石头,两人轮流取石头。每次能取小于石头个数且与石头个数互质的数量,当某人取时只有一颗石头则获胜。问先手是否可…

HTTPS 与 HTTP 的区别在哪?

HTTP与HTTPS作为互联网数据传输的核心协议,其通信机制与安全特性深刻影响着现代网络应用的可靠性与用户体验。它们有什么不同?HTTPS到底安全在哪里?HTTP与HTTPS作为互联网数据传输的核心协议,其通信机制与安全特性深刻影响着现代网络应用的可靠性与用户体验。本文将解析两者…

Featurewiz-Polars:一种强大且可扩展的特征选择解决方案,适用于XGBoost

前言:“Featurewiz-Polars”是一个用于特征工程的 Python 库,结合了特征选择和特征生成的功能。它基于“Polars”,这是一个高性能的 DataFrame 库,用于处理大型数据集,具有类似 Pandas 的 API 但更高效,尤其在处理大数据时。Featurewiz-Polars 专注于通过自动化方式,快速…

USACO2025FEB Gold T1 T2 题解

T3 等会补USACO2025FEB Gold 题解 赛时先看 T1,感觉很可做,推了一下发现能把问题转成在基环树上 dp。但我一下子没太想明白怎么解决“在基环树上找环”这个世纪难题,大概在一个小时 20 分钟的时候写完代码(值得一提的是这次罕见地一次就过了编译),交上去发现 WA 了大约一…

Windows10/Windows11系统快速安装杜比音效经典版教程指南

点击上方蓝字关注我 前言 在当今的数字娱乐时代,音频质量已经成为我们追求的重要部分。杜比音效,凭借其卓越的音质和沉浸式的听觉体验,成为了众多音频爱好者的首选,安装杜比音效经典版,提升电脑音频体验。无论是对于追求极致音质的音乐发烧友,还是渴望在观影和游戏时获得…

No.12 HTML5--新增标签

一、HTML5和HTMLHTML5是 HTML 最新的修订版本,2014年10月由万维网联盟(W3C)完成标准制定。 在 HTML5出现之前,我们一般采用 DIV+CSS 布局我们的页面。但是这样的布局方式不仅使我们的文档结构不够清浙,而且不利于搜索引擎爬虫对我们页面的爬取。为了解决上述缺点,HTML5新增…

ICLR 2025 | 无需训练的Token级 DiT加速方法

前言 本文分享 ICLR 2025 论文 ToCa: Accelerating Diffusion Transformers with Token-wise Feature Caching,提出的 ToCa 模型通过 token 粒度的缓存方法,实现了图像和视频生成模型上无需训练的两倍以上的加速。 欢迎关注公众号CV技术指南,专注于计算机视觉的技术总结、最…

Ⅱ.数据的机器级表示

章节导论: 2.1 位和数据类型 2.1.1 信息最小单位-位(0和1)(如高电压(0.9-1.1v)和低电压(0.0-0.2v)) 2.1.2 数据类型 2.2 整数 2.2.1 无符号整数 位置计数法:通过各个位置的数字不同的权重来表示一个数字 如286=2*102+8*101+6 ,在这个十进制系统中基数为10,同理,二进…