Hadoop、Spark、Flink Shuffle对比
一、Hadoop的shuffle
前置知识:
Map任务的数量由Hadoop框架自动计算,等于分片数量,等于输入文件总大小 / 分片大小,分片大小为HDFS默认值128M,可调
Reduce任务数由用户在作业提交时通过Job.setNumReduceTasks(int)设置
数据分配到Reduce任务的时间点,在Map任务执行期间,通过Partitioner(分区器)确定每个键值对的目标Reduce分区。默认采取partition=hash(key) % numReduceTasks策略
Shuffle过程:
hadoop会先将map数据写入缓冲区,缓冲区达到某个阈值后,会把数据溢写至磁盘,溢写磁盘时会根据先将数据写入相应分区文件,进行排序
溢写完毕后,会将多个分区文件合并,再进行归并排序
Reduce任务主动从所有Map任务的磁盘中拉取(Pull)属于自己分区的数据,拉取到数据后,还会进行一次归并排序
可以看到一共进行了三次排序。这一设计是后来所有分布式计算框架混洗任务的基石。
QA:为什么Hadoop需要三次排序?
第一次排序是为了第二次归并排序方便
第二次归并排序是为了给reduce任务时,reduce任务可以顺序读
第三次排序是因为hadoop要保证同一个reduce的输出是有序的,同时如果输入的key是有序的,reduce处理完输出即可,如果是无序的,那么reduce需要保存再重排序,对于数据量大的场景容易oom
二、Spark的shuffle
前置知识:
map个数由Saprk分区数计算或者自定义,reduce个数由用户指定,如果没指定,通常是机器核数
map和reduce数据的交互方式依旧是,map后把数据写入文件中,reduce从文件中读取数据
分区ID是数据在Shuffle过程中被分配到的目标Reduce任务的编号,决定了数据最终由哪个Reduce任务处理。
计算方式:
默认使用HashPartitioner,根据Key的哈希值对Reduce任务数取模:
分区ID=hash(key) % numReduceTasks分区ID=hash(key) % numReduceTasks
2.1 哈希混洗
Spark 1.2 之前默认的Shuffle机制
map输出的数据不再排序,若有M个map任务和R个reduce任务,每个map任务生成R个文件,每个reduce任务拉取属于自己的文件
这样导致文件句柄数太多了,若M=1000、R=1000,则生成 1,000,000个文件,同时内存压力也比较大,如果需要排序要在reduce端把一个key的所有数据全部加载,所以后面使用了sort混洗
2.2 sort 混洗
Spark 1.2 引入,逐步成为默认机制
1. Map任务处理输入数据,生成<Key, Value>对,并按分区ID暂存到内存缓冲区
2. 当缓冲区达到阈值(如spark.shuffle.spill.numElementsForceSpillThreshold默认值)时,开始排序。
-
排序规则:
-
仅按分区ID排序(默认):将数据按分区ID排序,同一分区内的数据无序。
-
按分区ID + Key排序(需配置):
若设置spark.shuffle.sort.byKey=true,则按(分区ID, Key)排序,同一分区内的数据按键有序。
-
3. 排序后的数据按分区ID顺序写入磁盘,生成一个临时溢写文件
4. Map任务结束时,将所有临时溢写文件合并为单个数据文件(data)和一个索引文件(index)
-
合并方式:
-
多路归并排序:将多个已按分区ID(或Key)排序的溢写文件合并,保持全局有序性。
-
索引文件生成:记录每个分区ID在数据文件中的起始和结束偏移量。
-
5. Reduce任务向Driver查询所有Map任务生成的数据文件和索引文件的位置
6. 若Map端已按Key排序,Reduce任务直接对多个有序数据块进行归并,生成全局有序数据集。
-
内存与磁盘结合:
-
数据量较小时,直接在内存中归并。
-
数据量较大时,使用外排序(溢出到磁盘,分批次归并
-
感觉这样下来,跟hadoop的shuffle就有点像了,这样有个好处是,map生成的文件就只有两个了,最终的文件就是 2 * R个
2.3 Spark和Hadoop shuffle的内存使用上的不同之处
Hadoop写文件时,是设置了一个内存阈值,到达了该阈值就会把内存内容写入文件中,比如阈值是80M,一个200M文件就要溢写三次,且缓冲区大小不可动态调整,无法根据任务需求扩展或收缩。
Spark 将内存划分为 存储内存(Storage Memory) 和 执行内存(Execution Memory),两者可动态借用,
-
Map 任务将数据按分区ID(或 Key)缓存在内存中。
-
溢出到磁盘:若内存不足,部分数据排序后写入磁盘临时文件。
-
合并最终文件:Map 结束时合并内存和磁盘数据,生成一个数据文件和一个索引文件。
举个spark处理数据的例子,假设有200MB数据:
(1) 内存排序
-
Map 任务处理数据后,先将键值对缓存在内存中,并按 分区ID(和可选的 Key)排序。
-
假设可用执行内存为 150MB,前 150MB 数据在内存中完成排序,生成一个 有序的内存块。
(2) 溢出到磁盘
-
当内存不足时,Spark 将内存中已排序的 150MB 数据 溢写到磁盘,生成一个临时文件(如
spill1),该文件内部保持有序。 -
剩余 50MB 数据继续在内存中排序,直到 Map 任务结束。
在 Map 任务结束时,所有内存和磁盘上的数据会被合并为一个全局有序的输出文件。具体流程如下:
假设 Map 任务生成以下两个有序片段:
-
内存块(150MB):
[A, B, D, F] -
溢写文件(50MB):
[C, E, G]
归并过程:
-
初始化指针:内存块指向
A,溢写文件指向C。 -
比较当前元素,选择最小者:
-
第一轮:
A(内存块) → 写入最终文件。 -
第二轮:
B(内存块) → 写入最终文件。 -
第三轮:
C(溢写文件) → 写入最终文件。 -
...
-
-
最终合并结果:
[A, B, C, D, E, F, G]。
reduce阶段拉取数据的时候,会优先从内存中获取,内存中没有才去文件中获取
三、Flink的shuffle
虽然Flink是批流一体的,因为Flink现在主要是作为流处理,所以我们分析Flink在流处理场景下的shuffle
因为Flink处理的是流数据,自然不会有上面介绍的批处理的那些从文件中拉取数据,文件归并排序之类的操作
如果硬要说的话,Flink是哈希混洗,用户定义上游算子和下游算子的并发度,上游算子的数据默认会采用 Round-Robin 轮询算法,通过rpc(netty)发给下游的算子,在Flink UI图中我们会看到图中的线是 Rebalance
如果有key by,那么会对key做hash,然后对并发度取模,根据取模结果发送给下游算子
相关文章:
Hadoop、Spark、Flink Shuffle对比
一、Hadoop的shuffle 前置知识: Map任务的数量由Hadoop框架自动计算,等于分片数量,等于输入文件总大小 / 分片大小,分片大小为HDFS默认值128M,可调 Reduce任务数由用户在作业提交时通过Job.setNumReduceTasks(int)设…...
本地部署 RAGFlow - 修改默认端口
本地部署 RAGFlow - 修改默认端口 1. 前提条件2. 部署 RAGFlow 1. 前提条件 确保 vm.max_map_count 不小于 262144: 如需确认 vm.max_map_count 的大小: sysctl vm.max_map_count如果 vm.max_map_count 的值小于 262144,可以进行重置&…...
repo init 错误 Permission denied (publickey)
一、已经生成ssh-key并设置到gerrit上 二、已经设置.gitconfig (此步骤是公司要求,设置gerrit地址为一个别名之类的,有的公司不需要) 然后出现下面的错误,最后发现忘记设置git的用户名和邮箱 1. git config --globa…...
Django settings.py 文件全解析
本篇详细介绍 Django settings.py 文件各个配置项的教程,涵盖核心配置项的作用及最佳实践 一、基础配置 1. BASE_DIR BASE_DIR Path(__file__).resolve().parent.parent作用:项目根目录路径,用于构建其他路径(如模板、静态…...
TSB - AD 解读 — 迈向可靠、透明的 TSAD 任务
目录 一 文章动机 二 TSAD 领域内的两类缺陷 三 数据集的构建 四 实验结果及结论 项目宣传链接:TSB-AD 代码链接: TheDatumOrg/TSB-AD: TSB-AD: Towards A Reliable Time-Series Anomaly Detection Benchmark 原作者解读:NeurIPS 2…...
下载 CSS 文件阻塞,会阻塞构建 DOM 树吗?会阻塞页面的显示吗?
下载 CSS 文件会对页面的渲染过程产生影响,具体是否阻塞 DOM 树的构建和页面的显示,取决于浏览器的渲染机制。 1. CSS 文件下载是否会阻塞 DOM 树的构建? 一般情况下,CSS 文件下载不会阻塞 DOM 树的构建: DOM 树的构建…...
6个月的Go语言学习甘特图路线图 从零基础到项目实战
以下是为期6个月的Go语言学习甘特图(2025年4月-2025年10月),包含详细阶段划分、对应资源及项目产出文档说明: #mermaid-svg-yQbkZCpCAXv6iXKC {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fi…...
论文阅读:2023-arxiv Can AI-Generated Text be Reliably Detected?
总目录 大模型安全相关研究:https://blog.csdn.net/WhiffeYF/article/details/142132328 文章目录 Abstract(摘要)1 Introduction(引言)Conclusion(结论) Can AI-Generated Text be Reliably D…...
查看IP地址/Ping 命令
目录 Windows Linux macOS Ping 命令 Windows 使用终端: 按下 Win R 键,打开“运行”对话框,输入 cmd 并按 Enter。 在命令提示符中输入 ipconfig,按 Enter。系统会显示网络适配器的详细信息,包括 IPv4 地址、子…...
Language Models are Few-Shot Learners,GPT-3详细讲解
GPT的训练范式:预训练Fine-Tuning GPT2的训练范式:预训练Prompt predict (zero-shot learning) GPT3的训练范式:预训练Prompt predict (few-shot learning) GPT2的性能太差,新意高&…...
鸿蒙编译框架@ohos/hvigor FileUtil用法
ohos/hvigor FileUtil用法 在鸿蒙(HarmonyOS)开发中,ohos/hvigor 的 FileUtil 是用于文件操作的实用工具类,提供了跨平台的文件读写、路径处理等常用方法。以下是其核心用法和示例: 一、核心方法说明 方法名功能描…...
Hoppscotch 开源API 开发工具
Hoppscotch 是一个开源的 API 开发工具,旨在为开发者提供一个轻量级、快速且功能丰富的 API 开发和调试平台。以下是对其主要特性和功能的详细介绍: 1. 轻量级与高效 Hoppscotch 采用简约的 UI 设计,注重易用性和高效性。它支持实时发送请求…...
Infura 简介
文章目录 Infura 简介Infura 的主要功能Infura 的替代方案(类似服务)AlchemyQuickNodeAnkrMoralisPocket Network 什么时候选择 Infura? Infura 简介 Infura 是一个 区块链基础设施即服务(BaaS, Blockchain as a Service…...
【芯片验证】面试题·对深度为60的数组进行复杂约束的技巧
朋友发给我的芯片验证笔试题,觉得很有意思,和大家分享一下。 面试题目 class A中一个长度为60的随机数组rand int arr[60],如何写约束使得: 1.每个元素的值都在(0,100]之间,且互不相等; 2.最少有三个元素满足勾股数要求,比如数组中包含3,4,5三个点; 请以解约束最快…...
Manus “Less structure,More intelligence ”独行云端处理器
根据市场调研机构Statista数据显示,全球的AR/AR的市场规模预计目前将达到2500亿美元,Manus作为VR手套领域的领军企业,足以颠覆你的认知。本篇文章将带你解读Manus产品,针对用户提出的种种问题,Manus又将如何解决且让使…...
【再读】R1-Onevision通过跨模态形式化为复杂多模态推理任务提供了系统性解决方案
R1-Onevision:跨模态形式化驱动的多模态推理技术突破,R1-Onevision通过跨模态形式化、双阶段训练和教育级基准测试,为多模态推理树立了新标杆。其技术创新不仅提升了模型在复杂任务中的表现,更重要的是为行业提供了一种可解释、可迁移的多模态处理范式。随着形式化方法的不断…...
Mysql-经典实战案例(3): pt-archiver 实现 MySQL 千万级大表分库分表(上)
零基础实战:使用 pt-archiver 实现 MySQL 千万级大表的水平分表(Hash分片) 本文适合人群:MySQL新手、想低成本实践数据库分表的开发者 环境要求:MySQL 5.7、Linux系统(建议CentOS/Ubuntu) 你将学…...
使用JSON存储数据的场景
Json 作为一种通用的数据格式,由于其结构灵活、可拓展等特点,在某些场景下我们也会直接将数据以 Json 格式存储到数据库中。 本文将探讨在开发中使用 JSON 存储数据的常见场景,并通过具体的实例帮助大家更好地理解其应用。 1. 半结构化数据…...
文生图网站推荐(2025.3)
以下是2024-2025年期间值得推荐的文生图网站,综合了免费性、中文友好度、操作便捷性及功能特色,涵盖不同用户需求: 一、国内主流平台 通义万相(阿里云) 特点:每日免费50次生成,模型和风格多样&a…...
网页制作代码html制作一个网页模板
制作一个简单而实用的网页模板:HTML基础入门 在数字时代,网页已成为信息展示和交流的重要平台。HTML(HyperText Markup Language)作为网页制作的基础语言,为开发者提供了构建网页的基本框架。本文将带你了解如何使用H…...
AI视觉测试工具实战评测:以Applitools为例的技术解析与行业应用
在数字化转型的浪潮中,软件界面(UI/UX)的复杂性与迭代速度呈指数级增长。传统的人工视觉测试不仅耗时费力,且难以应对多平台、多分辨率下的界面一致性问题。AI视觉测试工具的出现,通过智能图像识别与自动化对比&#x…...
SSM框架——Spring面试题
Spring常见面试题 Spring框架中的单例bean是线程安全的吗 不是线程安全的 Spring框架中有一个Scope注解,默认的值就是singleton,单例的。 因为一般在spring的bean的中都是注入无状态的对象,没有线程安全问题,如果在bean中定义了可…...
华为OD机试 - 计算观看演唱会场次(Java 2023 B卷 200分)
题目描述 为了庆祝中国共产党成立100周年,某公园将举行多场文艺表演。由于演出分布在不同的场地,一个人只能同时观看一场演出,且不能迟到早退。连续观看的演出之间最少需要有15分钟的时间间隔。小明是一个狂热的文艺迷,想观看尽可…...
云原生大佬重生,记忆逐步复苏(十三:selinux模块)
目录 1:什么是selinux 1.1 SELinux 的作用 1.2. SELinux 的工作原理 1.3. SELinux 的运行模式 2:解析selinux文件上下文标签策略 3:selinux的布尔值 4:调查和解决selinux问题 1:什么是selinux SELinux(Security-Enhanced L…...
Redis hyperloglog学习
背景知识 【伯努利试验】: 【伯努利试验】是一个概率论中的概念,指在相同的条件下重复进行n次独立的试验,每次试验只有两种可能的结果,且这两种结果发生的概率是固定的 抛硬币作为伯努利试验:在抛硬币时,我…...
MySQL高频八股——事务过程中Undo log、Redo log、Binlog的写入顺序(涉及两阶段提交)
大家好,我是钢板兽! 在上一篇文章中,我分别介绍了 Undo Log、Redo Log 和 Binlog 在事务执行过程中的作用与写入机制。然而,实际应用中,这三种日志的写入是有先后顺序的。因此,本篇文章将深入探讨它们的写…...
二阶近似 是什么意思
二阶近似 是什么意思 一、二阶近似的概念与举例 二阶近似是数学分析中通过泰勒展开对函数进行近似的方法,保留到二阶项(即包含一阶导数和二阶导数)。在优化问题(如模型训练)中,常用于近似损失函数,帮助更精准地更新模型参数。 举例: 假设损失函数为 L ( θ ) \mathc…...
Oracle GoldenGate 全面解析
Oracle GoldenGate 全面解析 Oracle GoldenGate 是一种实时数据集成和复制解决方案,广泛应用于数据同步、数据库迁移、高可用性和灾难恢复等场景。以下将详细解答您提出的关于 Oracle GoldenGate 的一系列问题。 1. Oracle GoldenGate 的架构组成及其核心组件的作用 架构组成…...
C++进阶——AVL树的实现
1、AVL的概念 1.1 AVL 树的发明 AVL 树由 G.M. Adelson-Velsky 和 E.M. Landis 在 1962 年的论文《An algorithm for the organization of information》中提出。他们的设计目标是解决二叉搜索树在动态操作(插入、删除)中可能退化为链表的问题。 1.2 …...
S32K144入门笔记(十三):LPIT的API函数解读
目录 1. SDK中的函数 2. API函数的释义 2.1 获取默认参数 2.2 初始化 2.3 启动与停止 2.4 计数值的设置于读取 2.5 中断API 1. SDK中的函数 在使用SDK的非抽象驱动函数时,函数的定义与声明在文件lpit_driver.c和lpit_driver.h中,一共有19个函数&a…...
