Hadoop总结
1.谷歌的三篇论文:《bigtable》 《GFS》 《Mapreduce》
2.hadoop是一个分布式存储和分析计算框架
3.hadoop组成部分:
1)hadoop common
2)hdfs
3) mapreduce
4) yarn
1.设计思想:
1)分块存储,默认是128MB
块的大小:
1.最小化寻址开销时间 块大小的选择参考一秒钟的传输速率 磁盘寻址时间在5~15ml 最优寻址时间是'一秒的百分之一'
2.节省内存的使用率 一个块的元数据大约150字节。无论存储的文件多大,都是占用相同的内存,所以hdfs不适合存储小文件
2.hdfs的优点:
-高容错性:副本冗余策略
-流式数据访问:一次写入,多次读取,保证数据一致性
-构建成本低
-适合大数据集
3.hdfs的缺点:
-高延迟
-不适合存储小文件
-不适合并发写入,文件随即修改:目前仅支持一个写者进行append操作。
三、hdfs的体系结构
1.hdfs采用的是master/slave主从架构,主要有四个部分组成:
client
namenode
datanode
secondaryNamenode
2.namenode:中心服务器:
-管理文件系统的命名空间和客户端的访问 并以fsimage 和editlog进行持久到本地
-在内存中维护数据块的映射信息,不会持久化到本地 block map
-实现副本冗余策略
-处理客户端的请求
3.datanode:
-存储数据
-执行数据的读写操作
-心跳机制 默认是3秒
-block report
4.secondaryNamenode:
-进行 fsimage 和 editlog 的合并
-不能实时同步,不能作为备份节点
5.client接口:
-与namenode进行交互,获取文件的存储位置(读/写两种操作)
-与datanode进行交互,写入或者读取数据
-上传文件是分块存储,读取是分片进行读取 一个分片是一个maptask
6.fsimage:
-命名空间镜像,是文件系统元数据的永久检查点,内部维护的是最近一次检查点的文件系统树和整棵树内所有的所有文件和目录的元数据。
7.editlog: -编辑日志文件:当hdfs文件系统进行操作产生的信息都会持久化到该文件中
1.开机启动过程
将fsimage加载到内存中->执行editlog中的操作->创建新的fsimage和editlog(hdfs的所有更新操作都会卸 载editlog中)->等待datanode的 blockreport 就是 产生blockmap
2.安全模式
namenode在开机启动过程中,会进入安全模式,namenode的文件系统对于客户端只是可读的,不能进行其他操作。
namenode在启动后,等待datanode的blockreport 只有当namenode接收到该报告后,客户端才能进行读
3.心跳机制 heartbeat
master启动时开启一个IPC服务,等待slave连接
slave启动后会主动连接ipc服务,每个三秒连接一次,并且汇报自己的信息
master收到slave发送的信息,并通过心跳机制下发命令
如果master长时间没收到slave的信息就认为slave挂掉了
超时时间计算:2*recheck+10*heartbeat 默认是的是 10分30秒
4.检查点机制
secondarynamenode合并fsimage和editlog两个文件的合并周期成为检查点机制
过程:
secondarynamenode请求namenode停止正在编辑的editlog,namenode会创建新的editlog,同时更新seed_txid文件。
secondarynamenode通过http协议拿到namenode上方的fsimage和editlogh文件
secondarynamenode进行合并写入新的文件 fsimage_x.ckpt文件中
secondarynamenode将新文件发送给namenode
namenode进行更名操作
5.机架感知
网络拓扑:在进行冗余策略时,需要考虑网络带宽。存储副本需要存储在哪个工作节点,哪个机架?
将网络看成一棵树,两个节点之间的距离就是他们距离最近共同祖先的距离总和
机架感知策略:第一个副本存放在client所处的节点上
第二个与第一个不同机架,随机选一个
第三个与第二个相同机架,不同节点
1.client发送上传请求到namenode
2.namenode收到请求,检查元数据,目录是否存在,检查文件是否存在
3.检查通过返回客户端,否则抛出异常
4.客户端收到结果开始分块。客户端向namenode请求上传第一块
5.namenode检查节点的负载均衡情况,找到三台机器 返回一组有序的节点信息 机架感知策略
6.客户端与datanode1建立连接 三个节点之间互相建立连接 并返回信息 是否建立成功
7.客户端收到建立成功的信息,开始写日志
8.将一块的数据读到内存中,按照packet的形式进行读取,发送到datanode1,1发送到2,2发送到3
9.返回是否上传成功的状态
10.上传成功,开始第二块,循环2-9步
11.上传成功,客户端通知namenode,更新元数据(将日志在元数据中操作一遍)
细节:
1.如果在上传过程中,dn3挂了怎么处理? 不处理,namenode等待区块报告,最后进行备份策略
2.dn3又启动了,怎么处理? dn3首先会向namenode注册,发送区块报告,namenode对比之前的数据,发现这是废数据,直接删除
3.要上传第一个块,在建立通道时,dn3挂了,怎么处理? 这一次的分配无效,namenode重新分配三台机器
4.在传输过程中,出现了丢包之类的怎么处理?重传(次数是有限制的,如果一直失败则整个过程失败)
具体处理:客户端有两个队列,一个是待调度队列,一个是调度队列,packet在调度队列中发送给待调度队列和datanode1,当失败时,会将等待队列中的包拿过来重新进行发送,会有次数限制。如果发送成功,收到了成功信号,则等待队列会删除队列中的packet.
5.如果block1,block2上传成功了,到block3时失败了,怎么办?在区块报告时,删除废数据,namenode重新分配三个节点。
6.如果block1 block2 上传成功了,但是block3上传时,如果客户端挂了,怎么处理?namenode等待消息超时,判断文件上传失败,清除废文件。
1. 客户端通过对DistributedFileSystem对象调用create()方法来新建文件
2. DistributedFileSystem对namenode创建一个RPC调用,在文件系统的命名空间中新建一个文件,此时该文件中还没有相应的数据块
3. namenode执行各种不同的检查,以确保这个文件不存在以及客户端有新建该文件的权限。如果检查通过,namenode就会为创建新文件记录一条事务记录(否则,文件创建失败并向客户端抛出一个IOException异常)。DistributedFileSystem向客户端返回一个FSDataOuputStream对象,由此客户端可以开始写入数据,
4. 在客户端写入数据时,FSOutputStream将它分成一个个的数据包(packet),并写入一个内部队列,这个队列称为“数据队列”(data queue)。DataStreamer线程负责处理数据队列,它的责任是挑选出合适存储数据复本的一组datanode,并以此来要求namenode分配新的数据块。这一组datanode将构成一个管道,以默认复本3个为例,所以该管道中有3个节点.DataStreamer将数据包流式传输到管道中第一个datanode,该datanode存储数据包并将它发送到管道中的第2个datanode,同样,第2个datanode存储该数据包并且发送给管道中的第三个datanode。DataStreamer在将一个个packet流式传输到第一个Datanode节点后,还会将此packet从数据队列移动到另一个队列确认队列(ack queue)中。
5. datanode写入数据成功之后,会为ResponseProcessor线程发送一个写入成功的信息回执,当收到管道中所有的datanode确认信息后,ResponseProcessoer线程会将该数据包从确认队列中删除。
1.客户端请求下载数据 namenode
2.namenode 检查元数据 ,数据存储在哪些节点上面 返回的文件的元数据信息(块顺序 和位置)
3.客户端与datanode建立连接 机架感知 就近原则
4.下载块数据
5循环3 4 步
检查点步骤
1.secondary申请checkpoint
2.namenode收到请求后进行日志回滚
3.secondary拉取 fsimage edits 进行合并(加载镜像和日志文件到内存中称为内存元数据)生成fsimage.checkpoint
4.将文件上传到namenode。
5.namenode进行数据的校验
6.将fsimage.checkpoint 改名 为 fsimage.xxx
如果nemenode磁盘损坏,元数据是否能够恢复?是否能完整恢复?
部分恢复:拿到secondary的fsimage
完整恢复:策略:一个主机上挂载了多个磁盘时。在配置文件中间将namenode元数据存储的路径设为多个,采用的是
复制的策略,将fsimage和edits放到多个磁盘下 datanode的存储路径是扩展存储空间
概念:yarn是hadoop的集群资源管理系统。为了改善mapreduce的实现,但是因为有足够的通用性,同样支持其他的分布式计算模式。
设计思想:将资源管理和作业监控/调度功能划分成单独的守护进程。其思想是拥有一个全局的ResourceManager和每个应用程序的ApplicationMaster。应用程序可以是单个作业,也可以是一组作业。
ResourceManager和NodeManager是yarn的两个长期运行的守护进程。提供核心服务
1.ResourceManager:管理整个集群上的所有资源分配,内部含有一个Scheduler(资源调度器)
2.NodeManager:是每台机器的资源管理器,负责启动和监视容器(container)的资源使用情况并向ResourceManager及其Scheduler报告使用情况
3.container:即集群上可使用资源,包含cpu 内存,磁盘
4.ApplicationMaster:与ResourceManager协商资源,并与NodeManager一起执行和监视任务
1.首先,客户端联系ResourceManager,要求它运行一个aplicationMaster进程
2.ResourceManager找到一个能够在容器中启动applicationMaster的节点管理器
2.1 找到一个NodeManager,该节点启动一个Container
3.applicationMaster通过心跳机制向ResourceManager请求更多的容器资源
4.applicationMaster运行起来之后需要做什么依赖于客户端传递的应用
-简单的运算后直接返回结果给客户端
-请求更多容器进行分布式计算
概念:Hadoop MapReruce是对Google提出的《Mapreduce》论文的开源实现。以可靠,容错的方式运行在分布式文件系统HDFS上的并行处理数据的编程模型。
核心思想:分而治之,移动计算不移动数据
MapTask的执行流程:
1.maptask调用FileInputFormat的getRecordReader读取分片数据
2.每次得到kv对, k是行偏移量 v是一行的数据 每次的kv调用一次map函数 然后调用context.write()
3.写出的数据交给收集器OutputCollector.collection()处理
4.将数据写入环形缓冲区,并记录起始位置,终止偏移量
5.当环形缓冲区内存达到80%,会进行溢写操作,溢写到磁盘中,溢写过程中数据继续写入到剩余的20%
6.在溢写前要进行分区,然后在分区中进行排序 分区规则是 key.hash % reduceNumber 排序是快排
7.当有多个溢写文件时,会两两进行合并 归并排序
ReduceTask的执行流程:
1.数据按照分区规则发送到reduceTask
2.reducetask将多个maptask的数据进行合并 归并排序
3.将key相同的进行分组
4.每一组调用一次reduce方法
5.reduceTask调用FileOutputFormat的write方法将数据写出
shuffle流程:就是数据从map写数据到环形缓冲区到reduce读取数据合并
combiner函数:在不影响结果的前提下,减少网络传输和磁盘IO.在map任务的输出指定一个combiner函数,其实就是运行在map端的一个reduce函数。 注意:在不影响结果的前提下才可以使用 平均值之类的不合适
partitioner
1.分区器是在map输出结果后 因此泛型是 k2,v2的类型
2.继承 partitioner类型
自定义分组器:WritableComparator 注意与自定义类型继承的接口 WritableComparable compareTo
1.重写compare方法
概念:Hadoop将MapReduce的输入数据分成等长的小数据块 称为 分片
hadoop为每一个分片构建一个单独的map任务。
分片和块的区别:分片是逻辑上的,分块是物理上的
分片大小的选择:
1.最佳分片大小应该和hdfs的块大小一致
2.分片不能过大或者过小。
创建分片的过程:
1.获取文件的大小和位置
2.判断文件是否可以分片(压缩格式有的可以进行分片,有的不可以)
3.获取分片的大小
4.剩余文件的大小/分片大小>1.1时,循环执行封装分片信息
分片规则:
第一个分片读到行尾再多读一行
既不是第一个分行也不是最后一个分片第一行数据舍弃,末尾多读一行
最后一个分片舍弃第一行,末尾多读一行
1.序列化:对象转化成二进制字节流 反序列化:字节流转换为对象
2.序列化的两个领域:永久存储 和 进程间通信
3.java序列化机制有很多冗余信息,在传输中占用大量的资源,导致有效信息传输效率降低,因此hadoop单独设计了一套序列化机制:Writable
4.Mapreduce的key和value都是可序列的化,针对key而言,还需要进行排序,所以还要提供比较接口 WritbaleComparable
5.自定义类型:实现writableComparable接口 并实现序列化反序列化方法 比较方法 compareTo
1.MR运行时,有五个独立的进程
-YarnRunner:用于提交作业的客户端程序
-ResourceManager:yarn资源管理器,负责协调集群上计算机资源的分配
-NodeManager:yarn节点管理器,负责启动和监视集群中机器上的计算机容器(container)
-Application Master:负责协调运行MapReduce作业的任务,它和任务都在容器中运行,这些容器有ResourceManager分配,并由NodeManager管理
-hdfs:共享作业所需要的文件
2.job的提交流程
1.客户端向resourcemanager提交作业
2.rm生成一个jobid和文件存储路径(路径就是id名),返回给客户端
3.客户端上传文件到hdfs对应的该路径下 并向rm汇报上传成功
4.rm将jobid放入到job调度队列中
5.rm调度job,首先rm分配一个资源(container) 其实就是找到一个nodemanager1
6.nm1到hdfs上拉取资源,例如jar包
7.nm1询问客户端启动命令是什么
8.客户端返回启动命令,例如 java -cp appmater
9.nm1启动appmaster (它知道job需要多少的资源)
10.appmaster向rm申请分配资源
11.被分配任务的节点到hdfs上拉取资源
12.任务节点与appmaster进行交互,申请启动命令 am会监控每一个maptask
13.当第一个maptask执行完成,reducetask可以启动 进行拉取数据 准备工作
14.am继续向rm申请分配资源,开始reducetask
思考问题:
1.被分配的节点怎么知道自己的任务是什么?
通过心跳机制,nodemanager向rm发送心跳机制,rm读取调度队列,rm会在调度队列中放入人物列表。 然后再返回命令中下达命令 任务列表信息
2.appmaster向rm申请资源,资源是多少呢?
分片机制:是由客户端来分配任务的,决定要多大的并行度
map阶段并行度:客户端首先确定待处理的目录下的数据量
循环遍历文件,并且对每一个文件执行 确定有多少块
将每一个block数量累加到计数器
返回一个任务列表的描述文件job.split
1.调度器的概念:Scheduler 根据容量,队列等限制条件(如每个队列分配一定的资源,最多执行一定量的作业等),将系统中的资源分配给各个正在运行的应用程序。
2.yarn中的三种调度器
1)FIFO Scheduler:先进先出,调度器将应用放入一个队列中,按照先后顺序进行运行应用。缺点:不适合共享集群,因为大的应用会占用集群的所有资源,所有应用都必须等待知道轮到自己
2)Capacity Scheduler 容量调度器
允许多个组织共享一个hadoop集群,一个独立的专门队列保证小作业一提交就可以运行
就是整个集群专门给小作业留了一部分资源,就算只有一个任务,也无法为它分配所有的资源,形成了资源浪费等
缺点:以整个集群的利用率为代价,大作业的执行时间要长上一些
3)Fair Scheduler 公平调度器
为所有运行的应用公平分配资源,使用公平调度器时,不需要预留资源,因为调度器会在所有运行的作业之间动态平衡资源。