导图社区 hadoop思维导图
这是一篇关于hadoop的思维导图。Hadoop是一个由Apache基金会所开发的分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序,充分利用集群的威力进行高速运算和存储。
编辑于2021-07-11 08:32:50hadoop
HDFS
基本概念
HDFS 适用的场景:
1) 存储非常大的文件: 适合于存储大文件
2) 一次写入、多次读取
HDFS的概述
分布式文件系统:
将数据的跨多台机器 来完成数据的存储工作
主要是用来存储海量数据(TB PB 以上级别)
HDFS 本质上就是一个分布式存储系统的软件, 通过这个软件, 实现将多个服务器的磁盘进行打通操作, 构建一个更大的存储空间, 交由HDFS进行管理, 而 数据, 最终都是落在各个服务器的本地磁盘上
组成部分
NameNode
管理元数据
配置副本策略
处理客户端读写请求
DateNode
存储实际的数据块。
执行数据块的读/写操作。
Secondary NameNode
定期合并 fsimage和fsedits,并推送给NameNode。在紧急情况下,可辅助恢复 NameNode
出现原因
如果NameNode执行了很多操作的话,就会导致edits文件会很大,那么在下一次启动的过程中,就会导致NameNode的启动速度很慢,慢到几个小时也不是不可能,所以出现了SecondNameNode。
几个机制
心跳机制
dn 每 3秒 向nn发送心跳包
如果超过10分钟未发生,nn会认为dn宕机了
dn会每隔6个小时向nn同步元数据信息
因为namenode的元数据是存储在内存中的,当集群重新启动的时候,datenode需要重新向namenode去发送自己的块信息
副本机制
数据块的备份数,默认是3个
当某个数据块的个数不够3个的时候,namenode 会自动新增该数据块的备份 超过3个的时候,会自动删除多余的部分。
当数据块不够3,并且无法新增数据块的时候, HDFS集群就会强制进入:安全模式,只能读,不能写。
负载均衡
namenode要保证各个datenode存储的数据块的个数和整体利用率保持一致。
机架感知
在存储一个文件的某一个副本的时候, 根据机架感知原理以及网络拓扑关系(寻最近机架),将第一个副本放置在某一个机架上, 剩下两个副本放到另一个机架的不同服务器上.
Hdfs的读写 流程
读
1) 客户端发送请求, 连接namenode, 请求写入数据操作
2) namenode接收到请求后, 首先要判断客户端用户是否具有写入权限, 如果没有, 直接报错, 如果有权限,接下来要判断在要写入的路径下是否有这个文件, 如果有, 直接报错, 如果没有, 通知客户端可以写入
3) 客户端接收到可以写入的信息后, 开始对文件进行切分, 形成多个block块
4) 客户端请求namenode, 第一个block应该存储在那些datanode中
5) namenode 根据机架感知原理以及网络拓扑关系 和 副本机制, 来寻找到对应的datanode的地址列表, 然后将这些datanode的地址列表返回客户端
6) 客户端从接收地址列表中, 拿出第一个地址与之连接, 形成一个pipeline的管道
7)当第一个连接成功后, 让第一个连接第二个地址, 然后第二个在连接第三个地址, 形成一个pipeline的管道
8) 客户端开始进行写入数据: 数据以 package 数据包(64kb)的形式来发送数据, 当第一台接收数据后, 然后将请求发送给第二个datanode, 然后第二个接收到以后,然后在发送给第三个datanode
9) 当第一个接收到数据后, 建立好一个应答响应队列, 当每个节点接收数据后, 都向应答队列反向报告, 最终所有都报告完成后, 将应答队列返回客户端
10) 不断的进行发送, 不断的进行应答响应, 即可完成数据的发送, 当第一个block发送完成后, 重新请求namenode第二个block应该存储在那些datanode中, 此时在从流程第5步, 往下走即可 ... 循环让所有的block写入成功即可
写
1) 向namenode发送请求, 连接namenode, 请求读取数据操作
2) namenode接收到请求后, 首先要判断客户端用户是否具有读取权限, 如果没有, 直接报错, 如果有权限接下来要判断在要写入的路径下是否有这个文件, 如果没有, 直接报错, 如果有, 根据机架感知原理以及网络拓扑关系 和 副本机制, 返回给客户端部分或者全部的block对应的datanode的地址信息列表
3) 客户端接收到地址列表后, 开始并行方式连接多个datanode的地址, 进行读取数据
4) 如果上一次返回的部分的block列表, 当读取完成后, 再次请求namenode, 获取剩余的部分或者全部的block对应的datanode信息在接着执行第三步, 进行读取数据操作, 直到将所有的block全部读取完成
SNN如何辅助NN
主要功能: 将edits文件和fsimage文件进行合并操作, 形成一个新的fsimage文件
edits文件,是namenode在运行过程中, 会将元数据更新, 新增 操作全部写入到edits文件中
fsimage文件, 是namenode元数据的镜像文件: 保存一份较为完整的元数据信息
执行流程:
1) SNN在时刻监控的NN中edits的文件, 当这个文件达到一定的阈值(时间1小时/大小64M)后,SNN会通知namenode, 进行关闭当前edits文件,然后滚动一个新的Edits文件
2) SNN 会基于http请求, 从NN中将edits文件和fsimage文件拷贝到自己的SNN的服务器磁盘上
3) SNN 将 edits文件和 fsimage文件统一加载内存中, 进行合并操作, 形成一个完整的fsimage文件
4) 将这个合并后的fsimage文件发送给NN, 替换掉原有Fsimage文件即可
联邦机制
主要是用来解决单台namenode 内存元数据有限的问题, 提供一种namenode的水平扩展功能
联邦机制类似于构建多个HDFS集群, 只不过这些集群使用同一份datanode. //这个问题绝大多数的公司都遇不到, 因为单服务器内存可以扩到1TB,
核心思想
对datanode 实施 命名空间操作. 将datanode划分成多个命名空间(数据库), 然后每个命名空间交给一个 namenode来管理, 多个namenode, 共享整个datanode.
弊端: 在写入数据, 可以通过不同的namenode来写入数据, 在获取的时候, 使用同一 namenode来获取数据, 否则拿不到(文件不存在)
安全模式
只能读,不能写
当hdfs刚刚启动的时候, 此时hdfs会自动进入到安全模式下, 此时, datanode在和namenode进行块的校验过程,对于用户而言, 无法对hdfs的进行数据写入操作, 只允许进行查询
如果发现hdfs中块的副本不够了, 而且还无法新增了, 此时系统自动进入安全模式, 直到手动修复 (将对应块所属文件删除)
MapReduce
子主题
mapreduce执行流程
map 有多少个文件切片就有多少个map(逻辑切块)
读取文件碎片
分区
写入环形缓冲区
溢写线程 (同时排序规约)
合并小文件
合并大文件,形成分好区排好序规好约的大文件
Map阶段的经历: 内存(环形缓冲区) -> 磁盘(临时小文件) -> 磁盘(合并后的最终MapTask结果文件)
1)假设HDFS中的某个文件被分成3个文件碎片,此时就会有3个MapTask任务分别去读取这三个文件碎片 每读取一行数据就会执行一次map方法将K1,v1,转换成k2,v2;
2)MapTask每处理好一条数据就会往外输出,执行分区操作,
3)执行好分区操作之后,就会将这些数据写入到环形缓冲区,
4)当环形缓冲区的占用率达到百分之八十时,就会开启一个溢写线程
5)将这些数据溢写到磁盘中,形成一个个临时小文件 十个小文件一合并 溢写的过程会执行排序操作,如果有规约也会执行规约操作
6)当MapTask任务完成之后,如果环形缓冲区里面还有数据,就会将这些直接溢写到磁盘中,这时磁盘中的多个临时小文件会Merge合并成一个大文件 最终形成一个 :分好区,排好序,规好约的大文件。
reduce 有多少个分区就有多少个reduce
//Reduce阶段的经历: 磁盘 -> 内存(copy线程) -> 磁盘(临时小文件) -> 磁盘(合并后的最终ReduceTask结果文件)
1)当reduceTask检测到mapTask全部都执行完成了, 开启copy(线程)的机制, 从多个mapTask中拷贝属于自己的分区的数据. //每个ReduceTask都会创建Copy线程, 只拷贝属于自己的分区的数据
2) 在copy过程中, 会先将数据写入到内存中, 当内存存储不下的时候, 在溢写到磁盘上, 形成临时文件
3) 当copy结束后, 会将所有溢写出来的临时文件全部合并(merge)为一个大文件, 此时在合并的过程中会对数据进行重新的排序工作, 如果reduce只有一个, 此时排序就是全局排序, 如果是多个, 依然是局部排序操作.
4) 对排序的好数据, 执行分组操作, 将相同key的value数据合并为一个集合, 每分好一组, 调用一次reduceTask中reduce方法.
5) reduce方法执行完成后, 将结果数据直接输出即可.
6) 输出组件就会将reduce的输出内容, 输出到目的地址上.
优化
优化思路:减少内存到磁盘 或者 磁盘到磁盘之间次数
具体操作:提高环形缓冲区的默认的大小, 将缓冲区设置和fileSplit的分片的大小为一致, 或者略高于fileSplit分片大小, 这样能减少临时文件的数量, 从而减少IO流的读写操作, 提高效率.
1) 数据输入
在执行MapReduce任务前,将小文件进行合并,大量的小文件会产生大量的map任务,增大map任务装载的次数,而任务的装载比较耗时, 从而导致MapReduce运行速度较慢。因此我们采用CombineTextInputFormat来作为输入,解决输入端大量的小文件场景。
2) Map阶段
A. 减少溢写(spill)次数:通过调整io.sort.mb及sort.spill.percent参数值,增大触发spill的内存上限,减少spill次数,从而减少磁盘IO。
B. 减少合并(merge)次数:通过调整io.sort.factor参数,增大merge的文件数目,减少merge的次数,从而缩短mr处理时间。
C. 在map之后,不影响业务逻辑前提下,先进行combine处理,减少 I/O。
3) Reduce阶段
A. 合理设置map和reduce数:两个都不能设置太少,也不能设置太多。太少,会导致task等待, 延长处理时间;太多,会导致 map、reduce任务间竞争资源,造成处理超时等错误。
B. 设置map、reduce共存:调整slowstart.completedmaps参数,使map运行到一定程度后,reduce也开始运行,减少reduce的等待时间。
C. 规避使用reduce:因为reduce在用于连接数据集的时候将会产生大量的网络消耗。 通过将MapReduce参数setNumReduceTasks设置为0来创建一个只有map的作业。
D. 合理设置reduce端的buffer. 默认情况下,数据达到一个阈值的时候,buffer中的数据就会写入磁盘,然后reduce会从磁盘中获得所有的数据。也就是说, buffer和reduce是没有直接关联的,中间多一个写磁盘-读磁盘的过程,既然有这个弊端, 那么就可以通过参数来配置,使得buffer中的一部分数据可以直接输送到reduce,从而减少IO开销。这样一来, 设置buffer需要内存,读取数据需要内存,reduce计算也要内存,所以要根据作业的运行情况进行调整。
4) Reduce阶段的调优属性
//当map task在执行到5%,就开始为reduce申请资源。开始执行reduce操作,reduce可以开始拷贝map结果数据和做reduce shuffle操作。
//在reduce过程,内存中保存map输出的空间占整个堆空间的比例。如果reducer需要的内存较少,可以增加这个值来最小化访问磁盘的次数
5) Shuffle阶段
Shuffle阶段的调优就是给Shuffle过程尽量多地提供内存空间,以防止出现内存溢出现象,可以由参数mapred.child.java.opts来设置,任务节点上的内存大小应尽量大。 我们在上面提到的属性参数,都是位于mapred-site.xml文件中,。
yarn
hadoop 1.x 和2.x的区别
1.X JobTracker存在问题:
1) 任务繁重, 既要进行资源分配, 又要进行任务分配.... 当MR任务比较多的时候, 有可能出现宕机风险
2) jobTracker存在单点故障的问题, 不允许有多个节点
3) 在 jobTracker上, 只能运行MR任务
2.X中 直接将mr集群 替换为 yarn集群:
1) jobTracker --> resourceManager 减少 resourceManager工作量(任务分配)
2) 允许 resourceManager 支持部署多个节点, 解决了单点问题
3) 可以运行其他的计算框架运行在yarn集群, 有yarn集群统一的资源分配 : MR spark storm ...
组成
ResourceManager 可以部署多个, 一般部署为2个
1) 接收客户端提交的任务请求
2) 在nodemanger上为每一个任务启动 applicationMaster程序
3) 负责资源的调度工作
4) 负责整个集群管理
nodemanager
负责执行的任务,基于容器(Container)的资源
applicationMaster
每一个任务都会有一个app Master
主要功能: 任务的分配
1) 计算当前这个任务, 需要启动多少个map 和 多少个reduce
2) 负责向resourceManager申请资源
3) 通知给各个nodemanager启动运行程序, 并且持续的监控这个程序的运行的状态
运行机制
三种调度器
FIFO Scheduler
先进先出的调度器
特性
当一个任务请求发来后, 如果采用使用FIFO调度器, 会将yarn集群中所有的资源全部调集过来,交给当前这个任务来运行,
后续的任务 因为没有的资源, 只能等待上一个任务执行完成
好处:
运行一些较大任务可以得到更多的资源
弊端:
如果这个较大的任务, 需要执行2小时, 但是后面的小任务只需要执行1分钟就搞定, 但是由于上一个任务,没有执行完成后, 第二个必须先等待2小时
capacity Scheduler (容量调度器)
特性:
首先先对yarn集群中所有资源进行划分为多个队列
比如说划分三个队列: A 队列 占据yarn集群中 50% 资源 ---主要运行比较大的MR B 队列 占据yarn集群中 30% 资源 ---主要运行一些小的MR任务 C 队列 占据yarn集群中 20% 资源 ---- 主要为其他的人员运行MR
当客户端在提交任务的时候, 可以指定将任务提交到那个队列中, 而且在运行过程中, 如果某一个任务运行在A队列中, 将yarn 50%全部都占用了, 依然满足不了需求, 此时可以允许其将其他队列资源拿过来使用
好处:
可以并行的运行多个MR的任务
弊端:
如果某一个大的任务将其他的队列中资源给占用了, 此时B 或者 C队列的资源减少, 此时如果B C任务比较多, 先去找占用资源队列, 归还资源, 如果占用资源队列, 没有执行完, 会一直占用着, 存在阻塞等待现象
Fair Scheduler
特性
首先先对yarn集群中所有资源进行划分为多个队列
比如说划分三个队列: A 队列 占据yarn集群中 50% 资源 ---主要运行比较大的MR B 队列 占据yarn集群中 30% 资源 ---主要运行一些小的MR任务 C 队列 占据yarn集群中 20% 资源 ---- 主要为其他的人员运行MR
当客户端在提交任务的时候,可以指定将任务提交到那个队列中, 如果某一个任务运行在A队列中, 将yarn 50%全部都占用了,依然满足不了需求, 此时可以允许其将其他队列资源拿过来使用(全拿走)
当所有资源都给了某一个任务执行, 在执行的过程中, 如果又有了一个新的任务被提交到了B队列中, 此时 公平调度器, 通知上一个任务, 将B队列的资源归还回来(平均归还), 支持抢占模式, 这样第二个任务就可以运行
如果这个时候, 又来一个任务, 提交到 C队列, 这个时候 A B队列中, 分别交出一部分资源, 交给 C队列的任务
此时: 三个任务: A B C各有一个任务, 每个人占 33.3%...
如果这个时候, 又来一个任务, 提交到 A队列, 公平调度器, 会通知A队列中上一个任务, 将你的资源切割一半出来交给第二个任务