spark-Join Key 的基数/rand函数

news2025/5/11 16:10:39

在数据处理中,Join Key 的基数 是指 Join Key 的唯一值的数量(也称为 Distinct Key Count)。它表示某个字段(即 Join Key)在数据集中有多少个不同的值。

1. Join Key 基数的意义

  • 高基数:Join Key 的唯一值数量较多,例如用户 ID、订单号等字段,每个值通常是唯一的。
  • 低基数:Join Key 的唯一值数量较少,例如性别(只有 “男” 和 “女” 两种值)、国家(通常只有几十到几百个值)。

Join Key 的基数直接影响 Join 操作的性能和数据分布,尤其是在分布式计算框架(如 Spark)中,基数的大小会影响数据的分区和 Shuffle 的效率。

2. Join Key 基数的计算

假设有一个数据表 orders,包含以下字段:

order_id | user_id | country
   1     |   101   |   US
   2     |   102   |   US
   3     |   103   |   UK
   4     |   101   |   US
   5     |   104   |   CA
计算基数的步骤
  1. 选择 Join Key 字段:假设我们选择 user_id 作为 Join Key。
  2. 统计唯一值数量
    • user_id 的唯一值为 {101, 102, 103, 104}
    • 基数为 4(即有 4 个不同的用户 ID)。

3. Join Key 基数对 Join 的影响

3.1 高基数的 Join Key
  • 定义:Join Key 的唯一值数量较多,接近数据集的总行数。例如订单号、用户 ID 等。
  • 特点
    • 数据分布通常较均匀,因为每个分区中 Join Key 的值都可能不同。
    • Shuffle 的数据量较大,但不会出现数据倾斜问题。
  • 适用 Join 类型
    • Sort-Merge Join:更适合高基数的 Join Key,因为数据分布均匀,排序和合并效率较高。
    • Broadcast Join:如果其中一个数据集较小,也可以使用广播机制避免 Shuffle。
3.2 低基数的 Join Key
  • 定义:Join Key 的唯一值数量较少,远小于数据集的总行数。例如性别(只有 “男” 和 “女” 两种值)。
  • 特点
    • 数据分布容易不均匀(数据倾斜),因为某些分区可能包含大量相同的 Join Key。
    • Shuffle 的数据量可能较小,但由于数据倾斜,某些分区的计算时间会显著增加。
  • 适用 Join 类型
    • Broadcast Join:如果其中一个数据集较小,广播机制可以避免数据倾斜。
    • Shuffle Hash Join:适合低基数的 Join Key,但需要注意数据倾斜问题。

4. Join Key 基数的实际应用场景

场景 1:高基数 Join Key
  • 示例
    • 表 A:user_id(100 万行,100 万个唯一值)。
    • 表 B:user_id(10 万行,10 万个唯一值)。
  • 分析
    • user_id 是高基数字段,数据分布均匀。
    • Spark 可以选择 Sort-Merge JoinBroadcast Join(如果表 B 较小)。
场景 2:低基数 Join Key
  • 示例
    • 表 A:country(100 万行,只有 3 个唯一值:US、UK、CA)。
    • 表 B:country(10 万行,只有 3 个唯一值:US、UK、CA)。
  • 分析
    • country 是低基数字段,数据分布可能不均匀(例如 US 的数据量远大于 UK 和 CA)。
    • Spark 可能选择 Shuffle Hash Join,但需要解决数据倾斜问题。

5. 如何优化基数对 Join 的影响

5.1 高基数 Join Key
  • 优化策略
    • 如果数据量较大且 Join Key 基数高,确保数据分区均匀,避免分区过多或过少。
    • 如果其中一个数据集较小,可以使用 Broadcast Join 避免 Shuffle。
5.2 低基数 Join Key
  • 优化策略
    1. 处理数据倾斜
      • 使用随机前缀对 Join Key 进行打散:
        val df1 = df1.withColumn("key", concat(col("country"), lit("_"), rand()))
        
- `RAND()`- 生成一个介于 `[0, 1)` 的随机浮点数。
  - 每行都会生成一个新的随机数。
- `FLOOR(RAND() * 10)`- 将随机数放大到 `[0, 10)` 的范围,并取整,生成一个随机整数(09)。
  - 这个整数作为随机前缀的一部分。
SELECT 
    *,
    CONCAT(country, '_', CAST(FLOOR(RAND() * 10) AS STRING)) AS key
FROM df1
 - 在 Join 后去除随机前缀,恢复原始数据。
  1. 使用 Broadcast Join
    • 如果其中一个数据集较小,可以广播小表,避免 Shuffle 和数据倾斜。
  2. 分区优化
    • 调整分区数,使得每个分区的数据量尽量均匀。

6. 总结

Join Key 基数定义特点适用 Join 类型优化策略
高基数唯一值数量较多,接近总行数数据分布均匀,Shuffle 数据量大,但不会出现数据倾斜Sort-Merge Join、Broadcast Join确保分区均匀,使用 Broadcast Join(如果小表较小)。
低基数唯一值数量较少,远小于总行数数据分布不均匀,容易出现数据倾斜Shuffle Hash Join、Broadcast Join处理数据倾斜(随机前缀打散、分区优化),使用 Broadcast Join(如果小表较小)。

7. 实际案例*

案例 1:用户订单分析
  • 场景:将用户表(user_id)与订单表(user_id)进行 Join。
  • 分析
    • user_id 是高基数字段,数据分布均匀。
    • 如果用户表较小,可以使用 Broadcast Join
    • 如果用户表较大,使用 Sort-Merge Join
案例 2:国家销售额分析
  • 场景:将销售表(country)与国家表(country)进行 Join。
  • 分析
    • country 是低基数字段,数据分布可能不均匀(如 US 数据量远大于其他国家)。
    • 可能出现数据倾斜问题,需要通过随机前缀或 Broadcast Join 优化。

6、 RAND() 生成随机数的原理

1.1 RAND() 的工作机制
  • 定义:RAND() 是 SQL 中用于生成随机数的函数,返回一个介于 [0, 1) 的浮点数
  • 随机数生成原理:
    • RAND() 使用伪随机数生成器(PRNG,Pseudo-Random Number Generator),基于一定的算法和种子(Seed)生成随机数。
    • 如果不指定种子,RAND() 每次调用都会基于系统当前状态(如时间戳)生成一个新的随机数。
    • 如果指定种子(如 RAND(seed)),则每次调用会生成相同的随机数序列。
1.2 RAND() 在多个表中的表现
  • 无种子情况下
    • 每次调用 RAND() 都会生成一个新的随机数
    • 在不同表中调用 RAND() 时,生成的随机数通常不同,因为它们基于各自的计算环境(如时间戳)。
  • 指定种子情况下
    • 如果在多个表中使用相同的种子(如 RAND(42)),则生成的随机数序列会相同
    • 这种情况下,可以确保不同表中的随机数一致。

2. 生成随机数不一致,导致关联不上解决方案

2.1 使用固定种子
  • 原理
    • 在多个表中使用相同的种子(如 RAND(42)),确保随机数生成逻辑一致。
    • 这样可以保证 country 的随机前缀在两个表中一致。
  • 实现
    SELECT 
        CONCAT(country, '_', CAST(FLOOR(RAND(42) * 10) AS STRING)) AS key
    FROM tableA;
    
    SELECT 
        CONCAT(country, '_', CAST(FLOOR(RAND(42) * 10) AS STRING)) AS key
    FROM tableB;
    
  • 效果
    • 表 A 和表 B 中的 country 值生成的随机前缀一致(如 US_7),确保 Join Key 匹配。
2.2 使用哈希函数
  • 原理
    • 使用哈希函数(如 MD5SHA)对 country 进行处理,生成一个固定的随机前缀。
    • 哈希函数的结果是确定性的,同样的输入会生成相同的输出。
  • 实现
    SELECT 
        CONCAT(country, '_', CAST(FLOOR(ABS(HASH(country)) % 10) AS STRING)) AS key
    FROM tableA;
    
    SELECT 
        CONCAT(country, '_', CAST(FLOOR(ABS(HASH(country)) % 10) AS STRING)) AS key
    FROM tableB;
    
  • 效果
    • 表 A 和表 B 中的 country 值生成的哈希前缀一致(如 US_7),确保 Join Key 匹配。
3.3 使用分组 ID 或预处理
  • 原理
    • 在数据预处理阶段,为每个 country 分配一个固定的分组 ID(如 US -> 0UK -> 1),然后在 Join Key 中使用分组 ID。
  • 实现
    • 在数据预处理阶段:
      SELECT 
          country,
          ROW_NUMBER() OVER (ORDER BY country) AS group_id
      FROM tableA;
      
    • 在 Join Key 中使用 group_id
      SELECT 
          CONCAT(country, '_', group_id) AS key
      FROM tableA;
      
      SELECT 
          CONCAT(country, '_', group_id) AS key
      FROM tableB;
      
  • 效果
    • 表 A 和表 B 中的 country 值生成的分组 ID 一致,确保 Join Key 匹配。
3.4 扩大随机数范围
  • 原理
    • 增加随机数的范围(如 RAND() * 100),减少随机前缀重复的概率。
    • 虽然不能完全解决随机数不一致的问题,但可以缓解数据倾斜问题。
  • 实现
    SELECT 
        CONCAT(country, '_', CAST(FLOOR(RAND() * 100) AS STRING)) AS key
    FROM tableA;
    
    SELECT 
        CONCAT(country, '_', CAST(FLOOR(RAND() * 100) AS STRING)) AS key
    FROM tableB;
    

4. 推荐方案

4.1 如果需要随机前缀一致性
  • 使用固定种子(如 RAND(42))或哈希函数(如 HASH(country))生成随机前缀,确保 Join Key 在多个表中一致。
4.2 如果需要减少数据倾斜
  • 扩大随机数范围(如 RAND() * 100),减少随机前缀重复的概率。
  • 或者在数据预处理阶段对 Join Key 进行分组。

5. 总结

方法是否解决随机前缀一致性问题是否解决数据倾斜问题适用场景
固定种子(RAND(seed))确保多个表的 Join Key 一致。
哈希函数(HASH)部分解决确保一致性,同时减少倾斜。
分组 ID需要预处理,适合复杂场景。
扩大随机数范围部分解决适合倾斜问题较轻的场景。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LLMs之ChatGPT:《Connecting GitHub to ChatGPT deep research》翻译与解读

LLMs之ChatGPT:《Connecting GitHub to ChatGPT deep research》翻译与解读 导读:这篇OpenAI帮助文档全面介绍了将GitHub连接到ChatGPT进行深度代码研究的方法、优势和注意事项。通过连接GitHub,用户可以充分利用ChatGPT强大的代码理解和生成…

【桌面】【输入法】常见问题汇总

目录 一、麒麟桌面系统输入法概述 1、输入法介绍 2、输入法相关组件与服务 3、输入法调试相关命令 3.1、输入法诊断命令 3.2、输入法配置重新加载命令 3.3、启动fcitx输入法 3.4、查看输入法有哪些版本,并安装指定版本 3.5、重启输入法 3.6、查看fcitx进程…

QT的初始代码解读及其布局和弹簧

this指的是真正的当前正在显示的窗口 main函数: Widget w是生成了一个主窗口,QT Designer是在这个主窗口里塞组件 w.show()用来展示这个主窗口 头文件: namespace Ui{class Widget;}中的class Widget和下面的class Widget不是一个东西 Ui…

Profinet转CanOpen网关,打破协议壁垒的关键技术

在石油化工行业的生产现场,各类自动化设备如同精密运转的神经系统,而通信协议则是传递信号的"语言"。当不同厂商的设备采用Canopen与Profinet这两种主流工业协议时,就像两个使用不同方言的专家需要实时协作,此时开疆智能…

引用第三方自定义组件——微信小程序学习笔记

1. 使用 npm 安装第三方包 1.1 下载安装Node.js 工具 下载地址:Node.js — Download Node.js 1.2 安装 npm 包 在项目空白处右键弹出菜单,选择“在外部终端窗口打开”,打开命令行工具,输入以下指令: 1> 初始化:…

SpringAI实现AI应用-使用redis持久化聊天记忆

SpringAI实战链接 1.SpringAl实现AI应用-快速搭建-CSDN博客 2.SpringAI实现AI应用-搭建知识库-CSDN博客 3.SpringAI实现AI应用-内置顾问-CSDN博客 4.SpringAI实现AI应用-使用redis持久化聊天记忆-CSDN博客 5.SpringAI实现AI应用-自定义顾问(Advisor&#xff09…

C#问题 加载格式不正确解决方法

出现上面问题 解决办法:C#问题 改成x86 不要选择anycpu

CentOS 7.9 安装详解:手动分区完全指南

CentOS 7.9 安装详解:手动分区完全指南 为什么需要手动分区?CentOS 7.9 基本分区说明1. /boot/efi 分区2. /boot 分区3. swap 交换分区4. / (根) 分区 可选分区(进阶设置)5. /home 分区6. /var 分区7. /tmp 分区 分区方案建议标准…

如何使用测试软件 Jmeter

第一步,点击 编辑 添加线程组 第二步,右键单击线程组,添加取样器 HTTP 请求 第三步,设置请求路径 第四步,添加 查看结果树 用于查看请求响应 最后点击绿色小三角启动即可

2025盘古石初赛WP

来不及做,还有n道题待填坑 文章目录 手机取证 Mobile Forensics分析安卓手机检材,手机的IMSI是? [答案格式:660336842291717]养鱼诈骗投资1000,五天后收益是? [答案格式:123]分析苹果手机检材&a…

系统分析与设计期末复习

第一章 系统的五个特性 整体性、目的性、相关性、环境适应性、层次性 软件系统的四个特性 复杂性、一致性、可变性、不可见性 第二章 系统规划 系统开发生命周期 系统规划->系统分析->系统设计->系统实施->系统运行维护->系统规划 诺兰阶段模型 阶段&a…

IBM BAW(原BPM升级版)使用教程第八讲

续前篇! 一、流程开发功能模块使用逻辑和顺序 前面我们已经对 流程、用户界面、公开的自动化服务、服务、事件、团队、数据、性能、文件各个模块进行了详细讲解,现在统一进行全面统一讲解。 在 IBM Business Automation Workflow (BAW) 中,…

从电动化到智能化,法雷奥“猛攻”中国汽车市场

当前,全球汽车产业正在经历前所未有的变革,外资Tier1巨头开始向中国智能电动汽车市场发起新一轮“猛攻”。 在4月23日-5月2日上海国际车展期间,博世、采埃孚、大陆集团、法雷奥等全球百强零部件厂商纷纷发布战略新品与转型计划。在这其中&am…

鸿蒙开发——3.ArkTS声明式开发:构建第一个ArkTS应用

鸿蒙开发——3.ArkTS声明式开发:构建第一个ArkTS应用 一、创建ArkTS工程二、ArkTS工程目录结构(Stage模型)三、构建第一个页面四、构建第二个页面五、实现页面之间的跳转六、模拟器运行 一、创建ArkTS工程 1、若首次打开DevEco Studio,请点击…

word换行符和段落标记

换行符:只换行不分段 作用:我们需要对它进行分段,但它是一个信息群组,我希望它们有同样的段落格式! 快捷键:shiftenter 段落标记:分段 快捷键:enter 修改字体格式或段落格式 …

AI时代的数据可视化:未来已来

你有没有想过,数据可视化在未来会变成什么样?随着人工智能(AI)的飞速发展,数据可视化已经不再是简单的图表和图形,而是一个充满无限可能的智能领域。AI时代的可视化不仅能自动解读数据,还能预测…

深入理解 TCP:重传机制、滑动窗口、流量控制与拥塞控制

TCP(Transmission Control Protocol)是一个面向连接、可靠传输的协议,支撑着绝大多数互联网通信。在实现可靠性的背后,TCP 引入了多个关键机制:重传机制、滑动窗口、流量控制 和 拥塞控制。这些机制共同协作&#xff0…

uniapp-商城-51-后台 商家信息(logo处理)

前面对页面基本进行了梳理和说明,特别是对验证规则进行了阐述,并对自定义规则的兼容性进行了特别补充,应该说是干货满满。不知道有没有小伙伴已经消化了。 下面我们继续前进,说说页面上的logo上传组件,主要就是uni-fil…

springboot 加载 tomcat 源码追踪

加载 TomcatServletWebServerFactory 从 SpringApplication.run()方法进入 进入到 refresh () 方法 选择实现类 ServletWebServerApplicationContext 进入到 AbstractApplicationContext onRefresh() 方法创建容器 找到加载bean 得到 webServer 实例 点击 get…

使用countDownLatch导致的线程安全问题,线程不安全的List-ArrayList,线程安全的List-CopyOnWriteArrayList

示例代码 package com.example.demo.service;import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;public class UnSafeCDTest {Executor…