当前位置: 首页 > article >正文

spark-Join Key 的基数/rand函数

在数据处理中,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 | country1     |   101   |   US2     |   102   |   US3     |   103   |   UK4     |   101   |   US5     |   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需要预处理,适合复杂场景。
扩大随机数范围部分解决适合倾斜问题较轻的场景。

相关文章:

spark-Join Key 的基数/rand函数

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

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进程…...

R语言学习--Day01--数据清洗初了解andR的经典筛选语法

当我们在拿到一份数据时,是否遇到过想要分析数据却无从下手?通过编程语言去利用它时发现有很多报错不是来源于代码而是因为数据里有很多脏数据;在这个时候,如果你会用R语言来对数据进行清洗,这会让你的效率提升很多。 …...

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> 初始化:…...

Docker、Docker-compose、K8s、Docker swarm之间的区别

1.Docker docker是一个运行于主流linux/windows系统上的应用容器引擎,通过docker中的镜像(image)可以在docker中构建一个独立的容器(container)来运行镜像对应的服务; 例如可以通过mysql镜像构建一个运行mysql的容器,既可以直接进入该容器命…...

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...

VTK|结合qt创建通用按钮控制显隐(边框、坐标轴、点线面)

文章目录 增加边框BoundingBox添加addBoundingBox添加BoundingBox控制按钮点击按钮之后的槽函数 添加坐标轴增加点线面显隐控制按钮添加控制点线面显隐的按钮到三维显示界面控制面显示槽函数控制线显示槽函数控制点显示槽函数 增加边框BoundingBox 增加边框BoundingBox并通过按…...

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

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

在过滤器中获取body中的json数据并且使得后续的controller层也能获取使用

前景提示: ①我需要在filter中获取到json数据->对key名首字母进行排序,然后拼接,进行验签 ②所以就需要在filer获取到json的数据,因为请求数据是一次性读取的流。如果过滤器中调用了request.json或request.get_json()&#xff…...

如何使用测试软件 Jmeter

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

2025盘古石初赛WP

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

系统分析与设计期末复习

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

最大公约数gcd和最小公倍数lcm

一、相关公式及其性质 文章只服务于竞赛,所以不会涉及证明。 辗转相除法:gcd(a, b) gcd(b, a % b); 直到 b 0,就可以知道上一层递归中的 a % b 0,所以上一层的 b 就是答案,也就是这一层递归的 a gcd(a, b) * lcm…...

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

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

视觉革命来袭!ComfyUI-LTXVideo 让视频创作更高效

探索LTX-Video 支持的ComfyUI 在数字化视频创作领域,视频制作效果的提升对创作者来说无疑是一项重要的突破。LTX-Video支持的ComfyUI便是这样一款提供自定义节点的工具集,它专为改善视频质量、提升生成速度而开发。接下来,我们将详细介绍其功…...

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

当前,全球汽车产业正在经历前所未有的变革,外资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时代的可视化不仅能自动解读数据,还能预测…...

spark基本介绍

Spark 是基于内存计算的分布式大数据处理框架,由加州大学伯克利分校 AMPLab 开发,现已成为 Apache 顶级项目。以下是其核心要点: 核心特点 1. 内存计算:数据可驻留内存,大幅提升迭代计算(如机器学习、图计算…...

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

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

MySQL 窗口函数入门到精通

目录 常用窗口函数速查表 1. 什么是"窗口"(不是你想的那种窗口) "窗口"≠电脑界面的窗口 那么,SQL 中的"窗口"是什么? 用表格形式理解"窗口"概念 2. 窗口函数解决了什么问题 场景…...

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

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

✍️【TS类型体操进阶】挑战类型极限,成为类型魔法师!♂️✨

哈喽类型战士们!今天我们要玩转TS类型体操,让你的类型系统像体操运动员一样灵活优雅~ 学会这些绝招,保准你的代码类型稳如老狗!(文末附类型体操段位表)🚀 一、什么是类型体操? &…...

联邦学习图像分类实战:基于FATE与PyTorch的隐私保护机器学习系统构建指南

引言 在数据孤岛与隐私保护需求并存的今天,联邦学习(Federated Learning)作为分布式机器学习范式,为医疗影像分析、金融风控、智能交通等领域提供了创新解决方案。本文将基于FATE框架与PyTorch深度学习框架,详细阐述如…...

springboot 加载 tomcat 源码追踪

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