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

大数据系列(四) Spark:比MapReduce快100倍,它做了什么?

Spark比 MapReduce 快 100 倍它做了什么大数据系列第 4 篇MapReduce 的继任者来了内存计算到底香在哪先讲个真事儿2014 年DatabricksSpark 背后的公司搞了个比赛用 Spark 和 MapReduce 分别跑一个机器学习算法逻辑回归迭代 10 轮看谁能更快完成。结果出来了MapReduce110 秒Spark6 秒18 倍的差距。而且数据量越大、迭代轮数越多差距越夸张。PageRank 跑 10 轮Spark 比 MapReduce 快 30 倍。当时整个大数据圈都炸了。大家突然意识到原来 MapReduce 中间结果落盘的设计是个巨大的性能陷阱。Spark 的创始人 Matei Zaharia 说了一句话“我们不是在优化 MapReduce我们是在重新思考分布式计算。”今天咱们就来看看Spark 到底做了什么能让性能提升这么多。Spark 的核心思想数据放在内存里MapReduce 最大的性能瓶颈是什么每轮计算都要读写磁盘。MapReduce 的迭代计算 第 1 轮: HDFS → Map → Shuffle → Reduce → 写 HDFS 第 2 轮: 读 HDFS → Map → Shuffle → Reduce → 写 HDFS 第 3 轮: 读 HDFS → Map → Shuffle → Reduce → 写 HDFS ... 每轮都要重新读盘、写盘磁盘 I/O 成为瓶颈Spark 的想法很简单第一轮从 HDFS 读数据之后把中间结果放在内存里下一轮直接从内存读。Spark 的迭代计算 第 1 轮: HDFS → 计算 → 内存缓存 第 2 轮: 内存 → 计算 → 内存缓存 第 3 轮: 内存 → 计算 → 内存缓存 ... 后续轮次直接从内存读避免了磁盘 I/O内存读写速度是磁盘的 100-1000 倍。这就是 Spark 性能飞跃的根本原因。但把数据放内存说起来简单做起来可不容易。分布式环境下机器随时可能挂内存里的数据丢了怎么办Spark 的解决方案是RDD。RDD弹性分布式数据集RDDResilient Distributed Dataset是 Spark 最核心的抽象。咱们拆开来看这三个词分布式DistributedRDD 的数据分散在集群的多台机器上每个机器存一部分叫一个Partition。┌─────────────────────────────────────────────────────────────────┐ │ RDD 分区示意 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 你的 RDD逻辑上是一个完整数据集 │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Partition 0 │ Partition 1 │ Partition 2 │ Partition 3 │ │ │ │ 机器 1 │ 机器 2 │ 机器 3 │ 机器 4 │ │ │ │ │ │ │ │ │ │ │ 数据子集 1 │ 数据子集 2 │ 数据子集 3 │ 数据子集 4 │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ 对 RDD 的操作 对每个 Partition 并行执行相同操作 │ │ │ └─────────────────────────────────────────────────────────────────┘弹性Resilient这是 RDD 最巧妙的设计。分布式环境下机器挂了是常态内存里的数据丢了怎么办Spark 的做法是不存数据本身只存数据从哪来、怎么算出来的。┌─────────────────────────────────────────────────────────────────┐ │ RDD 血统Lineage机制 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ HDFS 文件 │ │ │ │ │ ▼ textFile(hdfs://data.txt) │ │ RDD A ──→ flatMap(_.split( )) ──→ RDD B │ │ 拆分单词 │ │ │ │ │ ▼ map(word (word, 1)) │ │ RDD C ──→ reduceByKey(_ _) ──→ RDD D │ │ 按单词聚合 │ │ │ │ │ ▼ collect() │ │ 结果输出 │ │ │ │ 血统记录 │ │ • RDD B 来自 RDD A 的 flatMap 操作 │ │ • RDD C 来自 RDD B 的 map 操作 │ │ • RDD D 来自 RDD C 的 reduceByKey 操作 │ │ │ │ 容错场景 │ │ • 机器 3 挂了Partition 2 的数据丢了 │ │ • Spark 根据血统重新从 HDFS 读取对应数据 │ │ • 重新执行 flatMap → map → reduceByKey │ │ • 只重算丢失的分区不用重跑整个作业 │ │ │ └─────────────────────────────────────────────────────────────────┘RDD 会记录自己的血统Lineage——也就是我是从哪个 RDD 通过什么操作算出来的。如果某个分区的数据丢了Spark 根据血统信息重新计算这个分区就行。不需要像传统分布式系统那样全量复制数据来做备份。当然如果血统链太长比如几百轮迭代重算代价也很大。这时候可以用checkpoint()把 RDD 存到 HDFS切断血统链。数据集DatasetRDD 本质上就是一个不可变的、可分区的数据集合。你对 RDD 的操作不会修改它本身而是生成一个新的 RDD。RDD 的两种操作Transformation 和 ActionSpark 的操作分为两类这个区分很重要Transformation转换操作惰性求值Transformation 不会立即执行只是记录操作序列返回一个新的 RDD。// 这些操作都不会立即执行valrdd1sc.textFile(hdfs://data.txt)// 读取 HDFS 文件valrdd2rdd1.flatMap(_.split( ))// 拆分单词valrdd3rdd2.map(word(word,1))// 转换为 (word, 1)valrdd4rdd3.reduceByKey(__)// 按单词聚合// 到目前为止什么都没发生只是记录了要做这些事常见的 Transformation操作作用示例map()对每个元素做转换rdd.map(x x * 2)filter()按条件筛选rdd.filter(x x 10)flatMap()扁平化映射rdd.flatMap(_.split( ))reduceByKey()按 Key 聚合rdd.reduceByKey(_ _)groupByKey()按 Key 分组rdd.groupByKey()join()两个 RDD 关联rdd1.join(rdd2)distinct()去重rdd.distinct()Action行动操作触发执行遇到 ActionSpark 才会真正开始计算从血统的根节点一路算到当前 RDD。// 遇到 Action开始执行valresultrdd4.collect()// 把结果收集到 Driverprintln(result)// 其他 Actionrdd4.count()// 统计元素个数rdd4.take(10)// 取前 10 个rdd4.saveAsTextFile(hdfs://output)// 保存到 HDFSrdd4.foreach(println)// 遍历输出惰性求值的好处优化执行计划Spark 可以看到完整的操作链进行优化比如把多个 map 合并成一个避免不必要的计算如果某个 RDD 最终没被用到就不会执行DAG 调度比 MapReduce 聪明在哪MapReduce 的执行模型是固定的Map → Shuffle → Reduce。每个作业都要走这个流程哪怕你的计算逻辑很简单。Spark 的做法是把你的所有操作构建成一个DAG有向无环图然后智能地划分执行阶段。┌─────────────────────────────────────────────────────────────────┐ │ Spark DAG 与 Stage 划分 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 你的代码 │ │ rdd.map(...).filter(...).reduceByKey(...).map(...).collect() │ │ │ │ 构建的 DAG │ │ │ │ HDFS ──→ [map] ──→ [filter] ──→ [reduceByKey] ──→ [map] ──→ 结果│ │ 窄依赖 窄依赖 宽依赖 窄依赖 │ │ │ │ Stage 划分 │ │ │ │ ┌─────────────────────────┐ ┌─────────────────┐ │ │ │ Stage 0 │ │ Stage 1 │ │ │ │ HDFS → map → filter │ │ reduceByKey │ │ │ │ │ │ → map → 结果 │ │ │ │ 窄依赖流水线执行 │ │ 宽依赖需要 │ │ │ │ │ │ Shuffle │ │ │ └─────────────────────────┘ └─────────────────┘ │ │ │ │ │ │ └────────── Shuffle ────────────┘ │ │ │ │ 窄依赖Narrow Dependency父 RDD 的每个分区只被子 RDD │ │ 的一个分区使用如 map/filter可以流水线执行 │ │ │ │ 宽依赖Wide Dependency父 RDD 的每个分区被子 RDD 的多个 │ │ 分区使用如 reduceByKey/groupByKey需要 Shuffle │ │ │ └─────────────────────────────────────────────────────────────────┘Spark 的聪明之处在于Stage 内流水线执行窄依赖的操作可以在同一个 Stage 内流水线执行不需要等待所有父分区完成减少不必要的 ShuffleMapReduce 每轮都要 ShuffleSpark 只在宽依赖处 Shuffle内存缓存中间结果Stage 之间的中间结果可以缓存在内存供后续复用缓存让数据住在内存里Spark 提供了persist()和cache()方法让 RDD 驻留在内存中valrddsc.textFile(hdfs://data.txt).flatMap(_.split( )).map(word(word,1))// 缓存到内存rdd.cache()// 等价于 persist(MEMORY_ONLY)// 第一次 Action 触发计算结果缓存到内存rdd.reduceByKey(__).collect()// 第二次使用同一个 RDD直接从内存读取不用重新计算rdd.filter(_._1.startsWith(a)).count()Spark 支持多种持久化级别级别存哪是否序列化特点MEMORY_ONLY内存否默认速度快但耗内存MEMORY_ONLY_SER内存是省内存但 CPU 要解压MEMORY_AND_DISK内存磁盘否内存不够时溢写到磁盘DISK_ONLY磁盘否内存极度有限时用序列化Serialization就是把对象转成字节数组可以大幅减少内存占用但读取时需要反序列化消耗 CPU。Spark SQL让 SQL 党也能用 SparkSpark 最初只有 RDD API需要写 Scala/Java 代码。后来推出了 Spark SQL可以用 SQL 或者 DataFrame API 操作数据。// 用 SQL 写 Spark 作业valdfspark.read.parquet(hdfs://users.parquet)df.createOrReplaceTempView(users)valresultspark.sql( SELECT age, COUNT(*) as cnt FROM users WHERE gender M GROUP BY age ORDER BY cnt DESC )result.show()Spark SQL 背后有个Catalyst 优化器会自动优化你的查询谓词下推把过滤条件推到数据源层减少数据读取量列裁剪只读需要的列不读整行常量折叠编译期计算常量表达式Whole-Stage Code Generation把多个操作编译成一段 Java 代码消除虚函数调用这些优化对开发者完全透明你写 SQLSpark 帮你优化到底。Spark Streaming微批次流处理Spark 也支持流处理但采用的是**微批次Micro-batch**模型实时数据流 ──────┬──────┬──────┬──────┬──────┬──────┬──────► │Batch1│Batch2│Batch3│Batch4│Batch5│... │ 1s │ 1s │ 1s │ 1s │ 1s │ ▼ ▼ ▼ ▼ ▼ ┌─────────────────────────────────────────┐ │ 每个批次当作一个小 RDD用批处理引擎处理 │ │ map → filter → reduceByKey → output │ └─────────────────────────────────────────┘把实时数据流切成一小段一小段的比如每 1 秒一个批次每个批次当作一个 RDD 来处理。优点和批处理共用同一套引擎和 API开发简单。缺点延迟是秒级的做不到毫秒级实时。如果你需要毫秒级的实时处理得看下一篇的 Flink。Spark 生态一览Spark 不只是一个计算引擎它发展成了一个完整的生态组件作用对标产品Spark Core核心计算引擎RDD-Spark SQL结构化数据处理Hive、PrestoSpark Streaming流处理微批次Storm、FlinkMLlib机器学习库Scikit-learnGraphX图计算Neo4j、GraphLab一套技术栈批处理、SQL 查询、流处理、机器学习、图计算都能干。这也是 Spark 受欢迎的原因之一——学习成本低换场景不用换技术栈。Spark vs MapReduce差距到底在哪维度MapReduceSpark中间结果写磁盘内存缓存迭代计算每轮重新读 HDFS从内存直接读任务启动每轮作业重新启动 JVMExecutor 长期运行编程语言主要 JavaScala/Java/Python/R交互式查询不支持Spark Shell 支持延迟分钟/小时级秒级内存计算容错任务重算血统重算 CheckpointSpark 的核心优势就三点内存计算避免中间结果落盘迭代性能提升 10-100 倍DAG 调度智能划分执行阶段减少不必要的 Shuffle统一生态批处理、SQL、流处理、机器学习一套搞定小结今天咱们聊了 Spark核心思想内存计算避免中间结果落盘RDD弹性分布式数据集血统机制实现高效容错Transformation vs Action惰性求值优化执行计划DAG 调度窄依赖流水线执行宽依赖才 ShuffleSpark SQLCatalyst 优化器自动优化查询Spark Streaming微批次模型秒级延迟Spark 的成功告诉我们有时候性能瓶颈不在算法而在架构设计。MapReduce 的中间结果落盘设计在当时是合理的内存贵、机器容易挂但随着硬件发展内存计算成为了更优的选择。你用过 Spark 吗是写 RDD 还是 DataFrame/SQL有没有遇到过内存溢出的 OOM 问题欢迎聊聊

相关文章:

大数据系列(四) Spark:比MapReduce快100倍,它做了什么?

Spark:比 MapReduce 快 100 倍,它做了什么? 大数据系列第 4 篇:MapReduce 的"继任者"来了,内存计算到底香在哪? 先讲个真事儿 2014 年,Databricks(Spark 背后的公司&…...

阿里云代理商:阿里云部署的Hermes Agent 钉钉接入指南

在企业协作场景中,钉钉作为主流办公平台,承载着日常沟通、任务协同与信息流转的核心作用。Hermes Agent 作为轻量自进化 AI 智能体,与钉钉无缝对接后,可化身724小时在线的 “数字员工”,自动处理消息回复、数据查询、日…...

微步N10迷你主机评测:i3-N305性能与工业应用解析

1. 微步N10迷你主机开箱与硬件解析 作为一名长期关注迷你主机的技术爱好者,最近拿到了一台搭载Intel Core i3-N305处理器的微步N10迷你主机工程样机。这款产品最吸引我的是它在紧凑机身(14512854mm)内实现了丰富的工业级接口配置,…...

GitHub Copilot 6 月 1 日起转向基于使用量计费,能否解决成本难题?

GitHub Copilot 转向基于使用量计费这一举措反映了不断增长的计算需求和自主工作流程,要求首席信息官(CIO)重新思考预算编制和治理。随着对 AI 驱动的开发工作负载的需求增加,GitHub 正将其 Copilot 代码编写助手转向基于使用量的…...

使用 20 年后告别!Emacs 替代工具开发完成,新工具优势大

告别 Emacs2026 年 4 月 26 日,在日常使用了 20 年后,上周二最后一次在 Emacs 里输入了 C-x C-c。近 10 年已逐步减少对它的使用,先转向模态编辑,后改用 Vim。Emacs 是强大平台,早已习惯其各种应用,尤其是自…...

凭什么推荐大家使用湖南肯瑟的导热硅脂系列产品

为什么要选择肯瑟T408导热硅脂:想要高效散热又兼顾成本?肯瑟T408导热硅脂是你的绝佳选择!它拥有高导热率、低热阻、长效稳定的卓越性能,导热率达8W/mK,热阻仅0.02℃in/W,挥发率<0.5%。对比汉高&…...

【专利视点】光华经典案例九:“公开不充分”的案件获得授权

近年来,中国越来越重视创新及创新保护,越来越重视知识产权工作。知识产权已成为国家战略、高质量发展核心要素,也是企业赢得市场竞争、全球化布局的有力工具。恰逢上海光华专利事务所成立20周年,本所从代理的众多案例中精心选编了…...

恩施旅游服务商哪家好

恩施,宛如一个隐藏在深闺的绝美仙境,它以其独特的自然风光和深厚的民族文化吸引着无数游客前来探寻。然而,面对众多的旅游服务商,游客们常常会陷入选择的困境。毕竟一个好的旅游服务商直接关系到旅行的品质和体验。那么&#xff0…...

Netflix 风格的跨平台流媒体播放器

StreamBox Netflix 风格的跨平台流媒体播放器,对接 TVBox 生态片源。本仓库为 Monorepo,包含 Flutter 客户端和 JAR Bridge 中间服务。 预览 源码地址: https://github.com/huangj17/StreamBox-APP 仓库结构 目录说明技术栈READMEclient/Flutter 客户…...

Day 1 下午笔记:Linux 环境配置(SSH + JDK + Hadoop 初装)

一、SSH 免密登录配置1. SSH 是什么?SSH 是安全外壳协议,让你能安全地远程登录并操作另一台 Linux 服务器。2. SSH 客户端 vs 服务端角色作用类比客户端主动发起连接的那一方打电话的人服务端被动等待连接的那一方接电话的人3. 为什么需要配免密&#xf…...

仓颉解决“分数背包问题”

仓颉语言实现分数背包问题解析 分数背包问题是一种经典的优化问题,允许物品被分割装入背包。以下代码使用仓颉语言实现了该算法,包含核心逻辑和辅助函数。 核心数据结构与类定义 定义Item类表示背包中的物品,包含重量和价值属性: …...

“流水线冒险”,CPU如何解决

流水线技术通过将指令执行划分为多个阶段并行处理来提升CPU吞吐率,但这会引入“冒险”(Hazard)问题,即后续指令因依赖关系无法在预期时钟周期正确执行。主要冒险类型包括数据冒险、控制冒险和结构冒险。其中,数据冒险和…...

嵌入式USB通信设计:从基础到高级应用

1. 嵌入式USB通信基础与设计考量当我在2013年第一次将USB接口集成到工业传感器项目时,才真正理解这个看似简单的四线接口背后的复杂性。USB(Universal Serial Bus)作为现代嵌入式系统的标配接口,其优势不仅在于即插即用的便利性&a…...

XMGV系列微型音圈电机模组解析

在高端精密制造、自动化设备升级的浪潮中,微型音圈电机模组凭借紧凑结构与卓越性能,成为实现高精度直线运动的核心部件。XMGV系列微型音圈电机模组,以一体化集成设计、多元规格选择及定制化服务,精准适配各类严苛应用场景&#xf…...

【无标题】重磅!沉寂15个月,DeepSeek-V4预览版发布,开源大模型迎全新突破

等了整整15个月,DeepSeek-V4终于重磅登场!4月24日,DeepSeek正式发布V4预览版并同步开源,距离其去年1月发布R1版本,期间经历多次延期,市场质疑声不断。这段沉寂期里,AI行业竞争白热化&#xff1a…...

Golang goroutine泄漏怎么排查_Golang协程泄漏排查教程【实战】

协程泄漏需排除初始化波动和后台干扰,通过 runtime.NumGoroutine() 快速初筛,重点监控请求后不回落、压测后不恢复、长期单调上升三种情形;配合三处日志、pprof debug2 查阻塞栈,关注 chan receive/select/semacquire/IO wait 状态…...

名词、形容词、副词后缀

...

GEO管理系统有哪些功能?一篇讲透企业必用核心能力

AI搜索时代,GEO(生成式引擎优化)已经成为品牌抢占AI流量、提升品牌能见度的关键动作。但很多企业仍不清楚:GEO远不止一个关键词排名工具,而是一套覆盖监测、分析、优化、协同、复盘全链路的智能作战系统。今天带大家一…...

从Overleaf回迁本地:TexStudio搭配TexLive 2024的深度配置与效率提升指南

从Overleaf回迁本地:TexStudio搭配TexLive 2024的深度配置与效率提升指南 对于习惯使用Overleaf的科研工作者而言,云端LaTeX编辑器提供了开箱即用的便利,但随着项目复杂度提升,网络延迟、隐私顾虑和功能限制逐渐显现。本文将带您完…...

自动化工作流:全平台社交媒体评论区数据采集与关键词筛选系统

自动化工作流:全平台社交媒体评论区数据采集与关键词筛选系统 一、概述与设计目标 社交媒体平台已成为公众表达观点、分享生活和互动讨论的核心场所。以Facebook、Twitter(X)、Instagram、LinkedIn为代表的境外平台,以及微博、抖音、小红书为代表的境内平台,每天产生海量…...

告别传统天线:用紧耦合阵列(TCA)实现超宽带通信的保姆级原理拆解

告别传统天线:用紧耦合阵列(TCA)实现超宽带通信的保姆级原理拆解 想象一下,你正在用老式收音机调频,突然发现需要不断调整天线长度才能收听不同频段的节目——这正是传统天线面临的困境。而紧耦合阵列(TCA&…...

嵌入式Linux AI模型私有化部署完整技术方案

嵌入式Linux AI模型私有化部署完整技术方案 一、需求梳理与技术路线总览 1.1 需求分解 本方案需要满足六个核心部署需求: 开源模型私有化部署:使用公开可获取的模型,完全本地运行,不依赖云端API 嵌入式Linux系统支持:目标设备运行Linux内核,硬件资源受限 Linux原生开发…...

【node.js | Ubuntu | update】如何升级旧的nodejs本版至最新;如何升级npm

node.js | Ubuntu | update描述问题1 结果先升级了npm,就出问题了,反反复复是应该该先升级nodejsubuntu 更新的【方案一】 创建虚拟环境【方案二】安装openclaw的话可以参考官方[推荐]【方案三】docker 隔离更合理描述 如何升级旧的nodejs本版至最新 全…...

高德、百度、腾讯地图API混用?一份讲透国内主流坐标系差异与选型避坑指南

国内主流地图API坐标系混用实战指南:从原理到避坑 当你第一次在地图上看到自己所在的位置与实际相差几百米时,那种困惑感我至今记忆犹新。那是2016年,我们团队正在开发一个需要同时调用高德导航和百度POI搜索的物流调度系统。测试阶段&#x…...

基于51单片机智能恒温杯垫温度检测控制系统设计17-304

本设计由STC89C52单片机电路2路温度传感器DS18B20电路继电器电路按键电路1602液晶显示电路电源电路组成。1、液晶实时显示2个DS18B20检测的温度值。2、可以通过按键设置温度的阈值,如果第一个DS18B20检测到的温度高于阈值,停止加热,反之&…...

【ImportError: libGL.so.1】

解决方法&#xff1a;ImportError: libGL.so.1: cannot open shared object file: No such file or directory问题描述 在服务器运行import cv2 时报错 Traceback (most recent call last):File "/opt/data/private/InfiniteYou-main/test.py", line 22, in <modu…...

海康云眸Claw:以“数字员工”重塑零售连锁管理,提质增效降本!

当规模不再等同于效率从宏观视角看&#xff0c;连锁业态在中国快速发展与统一大市场格局相关&#xff0c;门店可跨区域复制等使连锁经营成高效组织形态。但规模扩大带来管理复杂度提升&#xff0c;企业数字化转型虽推进&#xff0c;现场管理仍是挑战。零售连锁行业门店分散等问…...

文本到图像生成技术演进与LatentMorph框架解析

1. 文本到图像生成的技术演进与核心挑战文本到图像&#xff08;Text-to-Image, T2I&#xff09;生成技术近年来取得了突破性进展&#xff0c;从早期的简单图像合成发展到如今能够生成高度逼真、语义一致的复杂场景。这一演进过程主要经历了三个关键阶段&#xff1a;1.1 早期生成…...

AI智能体安全防护:构建多层动态防御体系与工程实践

1. 项目概述&#xff1a;一个为AI智能体构建的“安全护栏”最近在搞AI智能体&#xff08;Agent&#xff09;开发的朋友&#xff0c;估计都遇到过同一个头疼的问题&#xff1a;你精心调教的智能体&#xff0c;一旦放开手脚去联网搜索、调用工具或者与用户深度对话&#xff0c;它…...

DolphinScheduler Agent 开源上线|从告警到自愈一键闭环,运维终于可以“躺着把活干了”

在 2026 Apache DolphinScheduler Meetup 技术分享中&#xff0c;由刘小东带来的 DolphinScheduler Agent 解决方案一经亮相&#xff0c;便成为社区焦点。这套打通「群聊告警→智能诊断→自动恢复→报告闭环」的全链路系统&#xff0c;可以很好地解决传统运维碎片化、高耗时、反…...