MapReduce海量数据并行处理 总结.docx
《MapReduce海量数据并行处理 总结.docx》由会员分享,可在线阅读,更多相关《MapReduce海量数据并行处理 总结.docx(74页珍藏版)》请在冰豆网上搜索。
MapReduce海量数据并行处理总结
MapReduce海量数据并行处理
复习大纲
Ch.1.并行计算技术简介
1.为什么需要并行计算?
提高计算机性能有哪些基本技术手段
提高字长,流水线微体系结构技术,提高集成度,提升主频
迫切需要发展并行计算技术的主要原因
1)单处理器性能提升达到极限
2)爆炸性增长的大规模数据量
2)超大的计算量/计算复杂度
2.并行计算技术的分类
有哪些主要的并行计算分类方法?
1)按数据和指令处理结构:
弗林(Flynn)分类
2)按并行类型
3)按存储访问构架
4)按系统类型
5)按计算特征
6)按并行程序设计模型/方法
1)按数据和指令处理结构:
弗林(Flynn)分类
SISD:
单指令单数据流
传统的单处理器串行处理
SIMD:
单指令多数据流
向量机,信号处理系统
MISD:
多指令单数据流
很少使用
MIMD:
多指令多数据流
最常用,TOP500高性能计算机
基本都属于MIMD类型
2)按并行类型分类
位级并行(Bit-LevelParallelism)
指令级并行(ILP:
Instruction-LevelParallelism)
线程级并行(Thread-LevelParallelism)
数据级并行:
一个大的数据块划分为小块,分别由不同的处理器/线程处理
任务级并行:
一个大的计算任务划分为子任务分别由不同的处理器/线程来处理
3)按存储访问结构分类
A.共享内存(SharedMemory)
所有处理器通过总线共享内存
多核处理器,SMP……
也称为UMA结构(UniformMemoryAccess)
B.分布共享存储体系结构
各个处理器有本地存储器
同时再共享一个全局的存储器
C.分布式内存(DistributedMemory)
各个处理器使用本地独立的存储器
B和C也统称为NUMA结构
(Non-UniformMemoryAccess)
4)按系统类型分类
多核/众核并行计算系统MC(Multicore/Manycore)或Chip-levelmultiprocessing,CMP
对称多处理系统SMP(SymmetricMultiprocessing)
多个相同类型处理器通过总线连接并共享存储器
大规模并行处理MPP(MassiveParallelProcessing)
专用内联网连接一组处理器形成的一个计算系统
集群(Cluster)
网络连接的一组商品计算机构成的计算系统
网格(Grid)
用网络连接远距离分布的一组异构计算机构成的计算系统
5)按并行程序设计模型/方法分类
共享内存变量(SharedMemoryVariables)
消息传递方式(MessagePassing)
MapReduce方式
3.并行计算的主要技术问题
并行计算有哪些方面的主要技术问题?
多核/多处理器网络互连结构技术
存储访问体系结构
分布式数据与文件管理
并行计算任务分解与算法设计
并行程序设计模型和方法
数据同步访问和通信控制
可靠性设计与容错技术
并行计算软件框架平台
系统性能评价和程序并行度评估
如何评估程序的可并行度(Amdahl定律)
程序能得到多大并行加速依赖于该程序有多少可并行计算的比例。
经典的程序并行加速评估公式Amdahl定律:
其中,S是加速比,P是程序可并行比例,N是处理器数目
根据Amdahl定律:
一个并行程序可加速程度是有限制的,并非可无限加速,并非处理器越多越好
并行比例vs加速比
50%=>最大2倍
75%=>最大4倍
90%=>最大10倍
95%=>最大20倍
4.MPI并行程序设计
MessagePassingInterface,基于消息传递的高性能并行计算编程接口
5.什么是MapReduce概念
MapReduce是面向大规模数据并行处理的:
(1)基于集群的高性能并行计算平台(ClusterInfrastructure),(硬件层)
允许用市场上现成的普通PC或性能较高的刀架或机架式服务器,构成一个包含数千个节点的分布式并行计算集群
(2)并行程序开发与运行框架(SoftwareFramework)(逻辑层)
系统自动提供了一个庞大但设计精良的并行计算软件构架,能自动完成计算任务的并行化处理,自动划分计算数据和计算任务,在集群节点上自动分配和执行子任务以及收集计算结果,将数据分布存储、数据通信、容错处理等并行计算中的很多复杂细节交由系统负责处理,大大减少了软件开发人员的负担
(3)并行程序设计模型与方法(ProgrammingModel&Methodology)(用户层)
借助于函数式Lisp语言中的设计思想,提供了一种简便的并行程序设计方法,用Map和Reduce两个函数编程实现基本的并行计算任务,提供了完整的并行编程接口,完成大规模数据处理
6.为什么MapReduce如此重要?
1)高效的大规模数据处理方法
2)第一个不同于冯诺依曼结构的、基于集群而非单机的计算方式的重大突破
3)目前为止最为成功的基于大规模计算资源的并行计算抽象方法
CH.2.MapReduce简介
1.MapReduce的基本模型和处理思想
1)对大数据分而治之;
2)构建抽象模型-Map和Reduce,用户仅需要描述做什么,不需要关心怎么做
3)提供统一的构架并完成以下的主要功能
·任务调度
·数据/代码互定位
·出错处理
·分布式数据文件管理
·Combiner和Partitioner(设计目的和作用)
2.Combiner和Partitioner设计目的和作用
带宽优化(Combiner的设计目的和作用),不会改变key-value的形式
用数据分区解决数据相关性问题(Partitioner的设计目的和作用)
例如:
有一个巨大的数组,其最终结果需要排序,每个Map节点数据处理好后,为了避免在每个Reduce节点本地排序完成后还需要进行全局排序,我们可以使用一个分区策略如:
(d%R),d为数据大小,R为Reduce节点的个数,则可根据数据的大小将其划分到指定数据范围的Reduce节点上,每个Reduce将本地数据拍好序后即为最终结果
Ch.3.Google/HadoopMapReduce基本构架
1.GoogleMapReduce的基本工作原理
1)GoogleMapReduce并行处理的基本过程
1.有一个待处理的大数据,被划分为大小相同的数据块(如64MB),及与此相应的用户作业程序
2.系统中有一个负责调度的主节点(Master),以及数据Map和Reduce工作节点(Worker)
3.用户作业程序提交给主节点
4.主节点为作业程序寻找和配备可用的Map节点,并将程序传送给map节点
5.主节点也为作业程序寻找和配备可用的Reduce节点,并将程序传送给Reduce节点
6.主节点启动每个Map节点执行程序,每个map节点尽可能读取本地或本机架的数据进行计算
7.每个Map节点处理读取的数据块,并做一些数据整理工作(combining,sorting等)并将中间结果存放在本地;同时通知主节点计算任务完成并告知中间结果数据存储位置
8.主节点等所有Map节点计算完成后,开始启动Reduce节点运行;Reduce节点从主节点所掌握的中间结果数据位置信息,远程读取这些数据
9.Reduce节点计算结果汇总输出到一个结果文件即获得整个处理结果
2)失效处理
主节点失效
主节点中会周期性地设置检查点(checkpoint),检查整个计算作业的执行情况,一旦某个任务失效,可以从最近有效的检查点开始重新执行,避免从头开始计算的时间浪费,主节点采用热备。
工作节点失效
工作节点失效是很普遍发生的,主节点会周期性地给工作节点发送检测命令,如果工作节点没有回应,这认为该工作节点失效,主节点将终止该工作节点的任务并把失效的任务重新调度到其它工作节点上重新执行。
3)计算优化
问题
如果有一个计算量大、或者由于某个问题导致很慢结束的Map节点,则会成为严重的“拖后腿者”。
解决方案
把一个Map计算任务让多个Map节点同时做,取最快完成者的计算结果
2.分布式文件系统GFS的基本工作原理
1)GoogleGFS的基本设计原则
廉价本地磁盘分布存储
多数据自动备份解决可靠性
为上层的MapReduce计算框架提供支撑
2)GoogleGFS的基本构架和工作原理
GFSMaster
Master上保存了GFS文件系统的三种元数据:
命名空间(NameSpace),即整个分布式文件系统的目录结构
Chunk与文件名的映射表
Chunk副本的位置信息,每一个Chunk默认有3个副本
前两种元数据可通过操作日志提供容错处理能力;
第3个元数据直接保存在ChunkServer上,Master启动或ChunkServer注册时自动完成在ChunkServer上元数据的生成;因此,当Master失效时,只要ChunkServer数据保存完好,可迅速恢复Master上的元数据。
GFSChunkServer
即用来保存大量实际数据的数据服务器。
GFS中每个数据块划分默认为64MB,这是因为处理的文件都比较大,所以设置成64MB比较合理
每个数据块会分别在3个(缺省情况下)不同的地方复制副本;
对每一个数据块,仅当3个副本都更新成功时,才认为数据保存成功。
当某个副本失效时,Master会自动将正确的副本数据进行复制以保证足够的副本数
GFS上存储的数据块副本,在物理上以一个本地的Linux操作系统的文件形式存储,每一个数据块再划分为64KB的子块,每个子快有一个32位的校验和,读数据时会检查校验和以保证使用为有效的数据。
数据访问工作过程
1.在程序运行前,数据已经存储在GFS文件系统中;程序实行时应用程序会告诉GFSServer所要访问的文件名或者数据块索引是什么
2.GFSServer根据文件名会数据块索引在其文件目录空间中查找和定位该文件或数据块,并找数据块在具体哪些ChunkServer上;将这些位置信息回送给应用程序
3.应用程序根据GFSServer返回的具体Chunk数据块位置信息,直接访问相应的ChunkServer
优点:
并发访问,解决mater拥堵。
3.分布式结构化数据表BigTable
1)BigTable设计动机和目标
需要存储管理海量的结构化半结构化数据
海量的服务请求
商用数据库无法适用
2)目标
广泛的适用性:
为一系列服务和应用而设计的数据存储系统,可满足对不同类型数据的存储和操作需求
很强的可扩展性:
根据需要可随时自动加入或撤销服务器节点
高吞吐量数据访问:
提供P级数据存储能力,每秒数百万次的访问请求
高可用性和容错性:
保证系统在各种情况下度能正常运转,服务不中断
自动管理能力:
自动加入和撤销服务器,自动负载平衡
简单性:
系统设计尽量简单以减少复杂性和出错率
2)BigTable数据模型—多维表
通过行、列、时间戳
一个行关键字(rowkey)
一个列关键字(columnkey)
一个时间戳(timestamp)
进行索引和查询定位的。
行:
列:
时间戳:
3)BigTable基本构架
主服务器
新子表分配
子表监控:
通过Chubby完成。
负债均衡:
子表服务器负载均衡操作
子表服务器
BigTable中的数据都以子表形式保存在子表服务器上,客户端程序也直接和子表服务器通信。
子表的基本存储结构SSTable,一个SSTable实际上对应于GFS中的一个64MB的数据块(Chunk),SSTable中的数据进一步划分为64KB的子块。
一个子表服务器上的子表将进一步由很多个SSTAble构成,每个SSTable构成最终的在底层GFS中的存储单位。
一个SSTable还可以为不同的子表所共享,以避免同样数据的重复存储。
子表寻址
子表地址以3级B+树形式进行索引;首先从Chubby服务器中取得根子表,由根子表找到二级索引子表,最后获取最终的SSTable的位置
4.Hadoop分布式文件系统HDFS
1)HDFS基本构架
2)HDFS数据分布设计
多副本数据块形式存储,按照块的方式随机选择存储节点,默认副本数目是3
3)HDFS可靠性与出错恢复
DataNode节点的检测
心跳:
NameNode不断检测DataNode是否有效
若失效,则寻找新的节点替代,将失效节点数据重新分布
集群负载均衡
数据一致性:
校验和checksum
主节点元数据失效
MultipleFsImageandEditLog
Checkpoint
5.HadoopMapReduce的基本工作原理
1)HadoopMapReduce基本构架与工作过程
HadoopMapReduce基本工作过程
1、运行作业
2、获取作业ID
3、复制作业资源
job.xml:
作业配置,例如Mapper,Combiner,Reducer的类型,输入输出格式的类型等。
job.jar:
jar包,里面包含了执行此任务需要的各种类,比如 Mapper,Reducer等实现。
job.split:
文件分块的相关信息,比如有数据分多少个块,块的大小(默认64m)等。
4、提交作业
调用JobTracker对象的submitJob()方法来提交作业.
JobTracker会把将jobid放入TaskScheduler变量中,然后以FIFO的方式进行调度。
当客户作业被调度时,JobTracker会创建一个对象JobInProgress,将有关此作也的任务和记录信息封装其中,以便跟踪任务的状态和进进程信息。
5、作业初始化
从HDFS中读取要执行的作业所对应的job.split,为初始化map任务的分配做好准备。
创建map任务和reduce任务.TaskTracker和JobTracker之间通过心跳机制来进行通信。
TaskTracker首先将自身的状态发送到JobTracker,并根据自身条件选择是向JobTracker请求新的Task。
JobTracker接收到TaskTracker的心跳后,如果发现TaskTracker在请求新的task,那么任务调度器就会将任务和任务信息封装起来,返回给TaskTracker。
当TaskTracker从JobTracker返回的心跳信息中获取新的任务信息时,它会将map任务或者reduce任务加入到对应的任务槽中。
6、执行作业
1.将job.split拷贝到本地;
2.将job.jar拷贝到本地;
3.将job的配置信息写入job.xml;
4.创建本地目录,解压job.jar;
5.调用lunchTaskForJob()方法发布任务
7、结果输出
对于执行的任务,所有TaskTracker任务的执行进度信息都会汇总到JobTracker中,当JobTracker接收到最后一个任务的已完成通知后,便把作业状态设置为“成功”,同时JobClient也会收到任务成功完成的通知,至此一个MapReduce任务就结束了。
2)HadoopMapReduce主要组件
文件输入格式InputFormat
定义了数据文件如何分割和读取,InputFile提供了以下一些功能:
选择文件或者其它对象,用来作为输入
定义InputSplits,将一个文件分开成为任务
为RecordReader提供一个工厂,用来读取这个文件
有一个抽象的类FileInputFormat,所有的输入格式类都从这个类继承这个类的功能以及特性。
当启动一个Hadoop任务的时候,一个输入文件所在的目录被输入到FileInputFormat对象中。
FileInputFormat从这个目录中读取所有文件。
然后FileInputFormat将这些文件分割为一个或者多个InputSplits。
通过在JobConf对象上设置JobConf.setInputFormat设置文件输入的格式。
输入数据分块InputSplits
InputSplit定义了输入到单个Map任务的输入数据
一个MapReduce程序被统称为一个Job,可能有上百个任务构成
InputSplit将文件分为64MB的大小,配置文件hadoop-site.xml中的mapred.min.split.size参数控制这个大小
mapred.tasktracker.map.taks.maximum用来控制某一个节点上所有map任务的最大数目
数据记录读入RecordReader
InputSplit定义了一项工作的大小,但是没有定义如何读取数据
RecordReader实际上定义了如何从数据上转化为一个(key,value)对的详细方法,并将数据输出到Mapper类中
TextInputFormat提供了LineRecordReader,读入一个文本行记录数据。
Mapper
每一个Mapper类的实例生成了一个Java进程(在某一个InputSplit上执行)
有两个额外的参数OutputCollector以及Reporter,前者用来收集中间结果,后者用来获得环境参数以及设置当前执行的状态。
现在的版本用Mapper.Context提供给每一个Mapper函数,用来提供上面两个对象的功能
Combiner
合并相同key的键值对,减少partitioner时候的数据通信开销
conf.setCombinerClass(Reduce.class);
是在本地执行的一个Reducer,满足一定的条件才能够执行。
Partitioner&Shuffle
在Map工作完成之后,每一个Map函数会将结果传到对应的Reducer所在的节点,此时,用户可以提供一个Partitioner类,用来决定一个给定的(key,value)对传输的具体位置。
Sort
传输到每一个节点上的所有的Reduce函数接收到得Key,value对会被Hadoop自动排序(即Map生成的结果传送到某一个节点的时候,会被自动排序)
Reducer
做用户定义的Reduce操作
接收到一个OutputCollector的类作为输出
最新的编程接口是Reducer.Context
文件输出格式OutputFormat
写入到HDFS的所有OutputFormat都继承自FileOutputFormat
每一个Reducer都写一个文件到一个共同的输出目录,文件名是part-nnnnn,其中nnnnn是与每一个reducer相关的一个号(partitionid)
FileOutputFormat.setOutputPath()
JobConf.setOutputFormat()
RecordWriter
TextOutputFormat实现了缺省的LineRecordWriter,以”key,value”形式输出一行结果。
3)容错处理与计算性能优化
由Hadoop系统自己解决
主要方法是将失败的任务进行再次执行
TaskTracker会把状态信息汇报给JobTracker,最终由JobTracker决定重新执行哪一个任务
为了加快执行的速度,Hadoop也会自动重复执行同一个任务,以最先执行成功的为准(投机执行)
mapred.map.tasks.speculative.execution
mapred.reduce.tasks.speculative.execution
6.Hadoop分布式文件系统HDFS编程
FileSystem基类
FileSystem是一个用来与文件系统交互的抽象类,可以通过实现FileSystem的子类来处理具体的文件系统,比如HDFS或者其它文件系统
通过factory方法FileSystem.get(Configurationconf)获得所需的文件系统实例
Configurationconf=newConfiguration();
FileSystemhdfs=FileSystem.get(conf);
Hadoop中,使用Path类的对象来编码目录或者文件的路径,使用FileStatus类来存放目录和文件的信息。
创建文件
create方法有很多种定义形式,但一般仅需使用简单的几种
publicFSDataOutputStreamcreate(Pathf);
publicFSDataOutputStreamcreate(Pathf,booleanoverwrite);
publicFSDataOutputStreamcreate
(Pathf,booleanoverwrite,intbufferSize);
打开文件
FileSystem.open方法有2个,参数最多的一个定义如下:
publicabstractFSDataInputStream
open(Pathf,intbufferSize)
throwsIOException
f:
文件名
buffersize:
文件缓存大小。
默认值:
Configuration中io.file.buffer.size的值,如果Configuration中未显式设置该值则是4096。
获取文件信息
FileSystem.getFileStatus方法格式如下:
publicabstractFileStatusgetFileStatus(Pathf)throwsIOException;
返回一个FileStatus对象。
FileStatus保存文件的很多信息,包括:
path:
文件路径
length:
文件长度
isDir:
是否为目录
block_replication:
数据块副本因子
blockSize:
文件长度(数据块数)
modification_time:
最近一次修改时间
access_time:
最近一次访问时间
owner:
文件所属用户
group:
文件所属组
如果想了解文件的这些信息,可以在获得文件的FileStatus实例之后,调用相应的getXXX方法(比如,FileStatus.getModificationTime()获得最近修改时间)
获取目录信息
获取目录信息,不仅是目录本身,还有目录之下的文件和子目录信息:
publicFileStatus[]listStatus(Pathf)throwsIOException;
如果f是目录,那么将目录之下的每个目录或文件信息保存在FileStatus数组中返回。
如果f是文件,和getFileStatus功能一致。
另外,listStatus还有参数为Path[]的版本的接口定义以及参数带路径过滤器PathFilter的接口定义,参数为Path[]的listStatus就是对这个数组中的每个path都调用上面的参数为Path的listStatus。
参数中的PathFilter则是一个接口,实现接口的accept方法可以自定义文件过滤规则。
文件读取
调用open打开文件之后,使用了一个FSDataInputStream对象来负责数据的读取。
通过FSDat