文章目录
CH1 MapReduce
MapReduce v1体系结构
- Client 客户端
- 用户编写的MapReduce程序通过Client提交到JobTracker端(一般通过命令行提交)
- 用户可通过Client提供的一些接口查看作业运行状态
- JobTracker
- 负责资源监控和作业调度
- 监控所有TaskTracker与Job健康状况,一旦发现失败,就将相应的任务转移到其他节点
- 跟踪任务的执行进度、资源使用量等信息,并将这些信息告诉任务调度器(TaskScheduler),调度器会在资源出现空闲时选择合适的任务去使用这些资源
- TaskTracker
- 监控Task运行的情况
- 周期性通过“心跳”将本节点上资源的使用情况和任务的运行进度汇报给JobTracker,同时接收JobTracker发送过来的命令并执行相应的操作(启动新任务、杀死任务等)
- 使用“slot”等量划分本节点上的资源量(CPU、内存等)。一个Task获取到一个slot后才有机会运行,Hadoop调度就是将各个TaskTracker上的空闲slot分配给Task使用。
- slot分为Map slot和Reduce slot,分别给MapTask和ReduceTask使用
- Task
- 分为Map Task和Reduce Task,均由TaskTracker启动
MapReduce v2体系结构
- 依旧是master/slave结构
- 主进程ResourceManager是整个集群资源仲裁中心
- 从进程NodeManager管理本机资源
Yarn在执行时包含以下独立实体:
- Client
- 客户端,负责向集群提交作业
- ResourceManager
- 集群主进程,仲裁中心,负责集群资源管理和任务调度
- 处理客户端作业提交请求
- 启动或监控ApplicationMaster
- 监控NodeManager
- 资源的分配与调度
- Scheduler
- 资源仲裁模块
- ApplicationManager
- 选定,启动和监管ApplicationMaster
- NodeManager
- 集群从进程,管理和监视Containers,执行具体任务
- 单个节点上的资源管理和任务管理
- 处理来自ResourceManager的命令
- 处理来自ApplicationMaster的命令
- Container
- 本机资源集合体,如某Container为4个CPU,8GB内存
- YARN会为每个任务分配一个Container,且该任务只能使用该Container中描述的资源
- 对任务运行环境进行抽象,封装CPU、内存等多维度的资源以及运行环境变量、启动命令等任务运行相关信息
- ApplicationMaster
- 任务执行和监管中心
- 每个应用有一个,负责应用程序整个生命周期的管理,负责协调来自ResourceManager的资源,并通过NodeManager监视容器的执行和资源的使用
- 负责数据的切分
- 为应用程序申请资源并分配给内部的任务
- 任务的监控与容错
MapReduce v2(Yarn)运行流程
- 作业提交:Client端向主进程ResourceManager的ApplicationManager模块提交任务(1),ApplicationManager按某种策略选中某NodeManager的某Container来执行此应用程序的ApplicationMaster(2)
- 任务分配:ApplicationMaster向Scheduler申请资源(3),Scheduler根据所有NodeManager发送过来的资源信息(4)和集群制定的调度策略以Container为单位给Application Master分配计算资源(5)
- 任务执行:ApplicationMaster向选定的NodeManager发送任务信息(包括程序代码、数据位置等信息),通知选中的NodeManager,让其启动本NM管理的Container计算任务(6)
- 进度和状态更新:处于计算状态的Container向其所在NodeManager汇报计算进度,NodeManager则通过心跳包,将这些信息再汇报给ApplicationMaster,ApplicationMaster则根据汇总过来的信息,给出任务进度
- 任务完成:所有任务完成后,信息一层层向上汇报到ApplicationMaster,ApplicationMaster再将结束信息汇报的ApplicationManager模块,ApplicationManager通知客户端任务结束
也有用这张图:(表述方式一样)
MapReduce的各个执行阶段
- 使用InputFormat模块做Map前的预处理;
- 将输入文件切分为逻辑上的多个InputSplit(InputSplit是MapReduce对文件进行处理和运算的输入单位,只是一个逻辑概念,没有对文件进行实际切割,只记录了要处理的数据的位置和长度)
- 通过RecordReader(RR)根据InputSplit中的信息来处理InputSplit的具体信息,加载数据并转换为适合Map任务读取的键值对,输入给Map任务
- Map任务根据用户自定义的映射规则,输出一系列的<key,value>作为中间结果
- shuffle:对Map的输出进行一定的分区、排序、合并、归并等操作,得到<key,value-list>形式的中间结果
- Reduce从多个Map读取数据,以一系列<key,value-list>中间结果作为输入,执行用户定义的逻辑,输出结果给OutputFormat模块(抽象类,下面有很多扩展的子类)
- OutputFormat模块会验证输出目录是否已经存在以及输出结果类型是否符合配置文件中的配置类型,如果都满足,就输出Reduce的结果到分布式文件系统
Shuffle过程
Map端的shuffle过程
-
每个Map任务分配一个缓存,MapReduce默认100MB缓存
-
设置溢写比例0.8(缓冲区数据/缓冲区大小)
-
分区默认采用哈希函数(对Map输出的key作hash取模,模为reduce任务数)
-
排序后可以合并,合并不能改变最终的结果;合并用来缩减中间节点的数据量,可选的操作(可做可不做)
-
在Map任务全部结束之前进行归并
-
归并得到一个大的文件(索引文件和数据文件),放在本地磁盘(同样经过分区与排序)
-
文件归并时,如果溢写文件数量大于预定值(默认是3)则可以再次启动Combiner,少于3不需要
-
JobTracker会一直监测Map任务的执行,并通知Reduce任务来领取任务
合并和归并的区别:
两个键值对<“a”,1>和<“a”,1>,合并得到<“a”,2>(计算),归并得到<“a”,<1,1>>(聚合)
Shuffle(混洗):输出到Reducer的数据为Mapper阶段经过排序的输出结果。在shuffle阶段框架将通过HTTP从恰当的Mapper的分区中取得数据
Sort(排序):该阶段框架将对输入到Reducer的数据通过key(不同的Mapper可能输出相同的key)进行分组。混洗和排序阶段是同时进行;map的输出数据被获取时会进行合并
Partition(分区):Partitioner对map输出的中间值的key(Reducer之前)进行分区。分区采用的默认方法是对key取hashcode。分区数等于job的reduce任务数,根据中间结果的key将数据传输到对应的reduce任务。HashPartitioner是默认的分区器
Reduce端的Shuffle过程
- 通过RPC向JobTracker询问Map任务是否已经完成,若完成则领取数据
- Reduce领取数据先放入缓存,来自不同Map机器,先归并再合并写入磁盘
- 多个溢写文件归并成一个或多个大文件,文件中的键值对是排序的
Ch3 Spark设计与运行原理
Spark简介
特点:
- 运行速度快:支持循环数据流与内存计算
- 容易使用:Scala、Java、Python和R语言进行编程,可以通过Spark Shell进行交互式编程
- 通用性:提供了完整而强大的技术栈,包括SQL查询、流式计算、机器学习和图算法组件
- 运行模式多样
Scala简介
是一门现代的多范式编程语言,运行于Java平台(JVM,Java虚拟机),并兼容现有的Java程序
特点:
- 强大的并发性,支持函数式编程,可以更好的支持分布式系统
- 语法简洁,提供优雅的API
- 兼容Java,运行速度快
Spark与Hadoop对比
Hadoop的MapReduce计算框架延迟高,只适用于离线批处理应用(批量计算),存在如下缺点
- 表达能力有限
- 磁盘IO开销大
- 延迟高
- 任务之间的衔接涉及IO开销
- 在前一个任务完成之前,其他任务就无法开始,难以胜任复杂、多阶段的计算任务
相比于Hadoop MapReduce,Spark具有如下优点
- Spark的计算模式也属于MapReduce,但不局限于Map和Reduce操作,还提供了多种数据集操作类型
- Spark提供了内存计算,可将中间结果放到内存中,对于迭代运算效率更高
- Spark基于DAG的任务调度执行机制,优于Hadoop MapReduce的迭代执行机制
使用Hadoop进行迭代计算非常耗资源
Spark将数据载入内存后,之后的迭代计算都可以直接使用内存中的中间结果作运算,避免了从磁盘中频繁读取数据
Spark生态系统
- Spark既能提供内存计算框架,也可以支持SQL即时查询、实时流式计算、机器学习和图计算等
- Spark可以部署在资源管理器YARN之上,提供一站式的大数据解决方案
Spark提供的生态系统能同时支持批处理、交互式查询和流数据处理
应用场景 | 时间跨度 | 其他框架 | Spark生态系统中的组件 |
---|---|---|---|
复杂的批量数据处理 | 小时级 | MapReduce、Hive | Spark |
基于历史数据的交互式查询 | 分钟级、秒级 | Impala、Dremel、Drill | Spark SQL |
基于实时数据流的数据处理 | 毫秒、秒级 | Storm、S4 | Spark Streaming |
基于历史数据的数据挖掘 | - | Mahout | MLlib |
图结构数据的处理 | - | Pregel、Hama | GraphX |
Spark架构设计
Spark运行架构包括集群资源管理器(Cluster Manager)、运行作业任务的工作节点(Worker Node)、每个应用的任务控制节点(Driver)和每个工作节点上负责具体任务的执行进程(Executor)
- 一个Application由一个Driver和若干个Job构成,一个Job由多个Stage构成,一个Stage由多个没有Shuffle关系的Task组成
- 当执行一个Application时,Driver会向集群管理器申请资源,启动Executor,并向Executor发送应用程序和文件,然后在Executor上执行Task,运行结束后,执行结果会返回给Driver,或者写到HDFS或者其他数据库中
Spark运行基本流程
- 为应用构建基本运行环境,即由Driver创建一个SparkContext,进行资源的申请、任务分配和监控
- 资源管理器为Executor分配资源,并启动Executor进程
- SparkContext根据RDD的依赖关系构建DAG图,DAG图提交给DAGScheduler解析成Stage,然后把一个个TaskSet提交给底层调度器TaskScheduler处理;Executor向SparkContext申请Task,Task Scheduler将Task发放给Executor运行并提供应用程序代码
- Task在Executor上运行,把执行结果反馈给TaskScheduler,然后反馈给DAGScheduler,运行完毕后写入数据并释放所有资源
特点:
- 每个Application都有自己专属的Executor进程,并且该进程在Application运行期间一直驻留。Executor进程以多线程的方式运行Task
- Spark运行过程与资源管理器无关,只要能够获取Executor进程并保持通信即可
- Executor有BlockManager存储模块
- Task采用了数据本地性和推测执行等优化机制
RDD运行原理
执行过程:(这一系列处理称为一个Lineage(血缘关系))
- RDD读入外部数据源进行创建
- RDD经过一系列的转换(Transformation)操作,每一次都会产生不同的RDD,供给下一个转换操作使用
- 最后一个RDD经过“动作”操作进行转换,并输出到外部数据源
RDD运行过程
- 创建RDD对象
- SparkContext负责计算RDD之间的依赖关系,构建DAG
- DAGScheduler负责把DAG图分解成多个Stage,每个Stage中包含了多个Task,每个Task会被TaskScheduler分发给各个WorkerNode上的Executor去执行