◆Hadoop是什么?
Apache下的开源的、分布式文件存储和计算框架,用于处理大规模数据集的存储和处理。
◆HDFS的读写流程
写入数据流程:
1. client 发起文件上传请求,通过 RPC 与 NameNode 建立通讯,NameNode 检查目标文件是否已存在,父目录是否存在,返回是否可以上传;
2. client对文件进行切分,形成若干数据块
3. client 先向namenode请求第一个数据块的上传
4. namenode 根据机架感知原理和网络拓扑关系,找到可以上传的datanode的连接列表,返回给client
5. client 从连接列表中选择第一台datanode与之建立pipeline(管道)
6. 当连接第一台之后,接着让第二台与第一台连接,第三条与第二台连接,依次形成一条pipeline(管道)
7. 数据被分割成一个个 packet 数据包在 pipeline 上依次传输,进行备份。
8. 在 pipeline 反方向上,每个节点逐个给予应答响应(ack 应答机制),最终由pipeline中第一个 DataNode 节点A将 pipeline ack 发送给client;
9. 当第一个数据块发送完成后,clinet重新请求namenode获取第二个数据块上传,从第5步继续开始执行,直到所有的数据块全部写入完成
10. namenode将存储数据的元数据持久化到磁盘上
读取数据流程:
- Client 向 NameNode 发起 RPC 请求,来确定请求文件 block 所在的位置;
- NameNode 会视情况返回文件的部分或者全部 block 列表,对于每个 block,NameNode 都会返回含有该 block 副本的 DataNode 地址;
- 这些返回的 DataNode 地址,会按照集群拓扑结构得出 DataNode 与客户端的距离,然后进行排序。(排序的两个规则:网络拓扑结构中距离Client近的排靠前;心跳机制中超时汇报的 DataNode 状态为 STALE,这样的排靠后);
- Client 选取排序靠前的 DataNode 来读取 block,如果客户端本身就是 DataNode,那么将从本地直接获取数据;底层上本质是建立 Socket Stream(FSDataInputStream),重复的调用父类 DataInputStream 的 read 方法,直到这个块上的数据读取完毕;
- 当读完列表的 block 后,若文件读取还没有结束,客户端会继续向 NameNode 获取下一批的 block 列表;
- 读取完一个 block 都会进行 checksum 验证,如果读取 DataNode 时出现错误,客户端会通知 NameNode ,然后再从下一个拥有该 block 副本的 DataNode 继续读。
- read 方法是并行的读取 block 信息,不是一块一块的读取;NameNode 只是返回 Client 请求包含块的 DataNode 地址,并不是返回请求块的数据;
- 最终读取来所有的 block 会合并成一个完整的最终文件。
◆Shuffle的流程
Shuffle是在大数据处理中,将数据重新分区、重新组合的过程。
在hadoop中,从数据处理的角度来看,shuffle发生在数据通过mapper.map方法处理后 到 数据进入reducer.reduce方法的过程。
Maptask阶段
在mapper.map执行完毕后,将K,V 读取到环形临时缓冲区,此时,会进行快速排序,当缓冲区满足条件时,会发生溢写,根据key 进行分区,将数据写入到文件中。在maptask溢写完毕后,产生若干个文件,在此之后map端会将这些文件进行分区合并,并进行归并排序,如果combiner被调用,则在此时进行,一个分区只产生一个文件。
Reducetask阶段
从各个maptask节点下载对应分区的文件,然后按照分区进行合并文件,并按照Key分组 合并value,此时,会进行一次归并排序,然后循环调用reducer.reduce方法处理数据。
◆Mapduce的执行流程
提交任务
根据文件大小进行逻辑切片,默认大小为128M,每次切片前会做比较,文件大小大于默认大小的1.1倍,才会切片。
maptask阶段
1、读取切片后的数据(优先读取本地的数据切片)
2、循环调用mapper.map方法,输出k v
3、kv 输出到环形缓冲区,根据键值对进行快速排序,当缓冲区达到80%的容量时,会根据进行溢写。
4、溢写出较多的小文件,此时会进行分区合并,每个分区只保留一个文件,此时,若combiner被调用,则在此时进行处理。
Reducetask阶段
- 从各个maptask拉取到若干分区文件,进行合并
- 根据key进行将value聚合并进行归并排序。
- 然后循环调用reducer.reduce方法处理数据
- 输出key-value ,将数据写入HDFS中
◆Yarn的调度流程
1.MR程序提交到客户端所在的节点
2.yarnrunner 向 RM 申请一个applicationmaster
3.RM 将应用程序的资源路径返回给 yarnrunner
4.该程序将运行所需的资源提交到hdfs上,(job.xml;job.split;mr.jar)
5.程序资源提交完成后,申请运行mram
6.RM将用户的请求初始化成一个task
7.其中一个nodemanager 领取到task任务
8.该nm 创建容器container 并产生MRAM
9.container 从 hdfs 上拷贝资源到本地
10. MRAM向RM 申请运行 maptask
11.RM将运行maptask任务分配给另外两个nm ,另外两个nm 分别领取任务并创建容器
12. MRAM向两个接收到的任务的nm发送程序启动脚本,nm分别启动maptask
13. MRAM向RM 申请两个容器,运行reduce task
14.reduce task 从 maptask 所在的节点上拉取相应的分区数据,进行任务
15.程序运行完成后,MRAM向 RM申请注销
◆Yarn调度器
FIFO调度器(依次排队)
一个典型的先进先出(FIFO)的容器,放入容器的顺序与取出的顺序相同,它不考虑任务的优先级、资源需求或执行时间,只按照任务提交的顺序进行调度。FIFO调度器没有资源隔离的概念,所有任务共享集群的资源。
适用于单用户、单任务、不需要资源隔离和预测性的场景。由于不具备资源隔离和优先级管理,不适用于多用户或多任务同时运行的情况。实际上不太适用工作场景
容量调度器 ( capacity scheduler) (根据资源大小分配,资源抢占)
带有层级队列的容量调度器:在同一个队列中,使用FIFO调度策略进行调度.
带有延迟调度的容量调度器:试图以本地请求为重进行调度
容量调度器允许用户预先定义多个队列,并为每个队列分配一定的资源容量。每个队列都可以使用预先分配的容量,保证了每个应用程序的资源隔离和预测性。容量调度器支持多用户和多队列,并允许按照资源需求和优先级进行调度。
适用于多用户、多队列、资源共享的情况,允许实现资源隔离和预测性。容量调度器适用于复杂的多任务、多用户同时运行的场景。
公平调度器(Fair scheduler)(一人一部分,谁也别抢谁的)
采用公平调度算法,将集群资源以公平的方式分配给不同的应用程序。它尝试在每个时刻将资源均匀地分配给所有应用程序,避免出现饥饿的情况。公平调度器支持多个队列,每个队列的资源按照比例进行分配。
适用于需要资源公平分配的场景,不需要预先设定固定的容量,适用于多用户、多任务的场景。
◆NameNode工作机制
1.命名空间管理:Namenode维护文件系统的整个目录结构,包括文件、目录、权限、所有者、块位置等信息。它通过树状结构来表示文件系统的目录层次关系,并保存在内存中。
2.元数据存储:Namenode负责存储文件系统的元数据,包括文件和目录的名称、权限、大小、块的位置等信息。这些元数据存储在内存中,并通过两个文件进行持久化存储:fsimage文件和edits日志文件。
3.文件块映射:Namenode维护文件到块的映射关系,记录每个文件由哪些块组成以及块的位置。这样,当客户端读取或写入文件时,Namenode能够快速定位块所在的数据节点。
4.块报告:数据节点会定期向Namenode发送心跳,同时汇报本地存储的块信息。Namenode通过接收这些块报告,保持对数据节点和块状态的实时监控。
5.客户端交互:当客户端请求读取、写入或删除文件时,首先会与Namenode进行交互。Namenode根据文件的元数据信息,告诉客户端哪些数据块存储在哪些数据节点上,并协助客户端进行数据读写操作。
6.容错机制:Namenode是HDFS的单点故障,因此它本身也会有容错机制。Namenode会定期将内存中的元数据快照(fsimage)和最近的变更日志(edits)写入持久化存储,以便在发生故障时进行恢复。
◆SecondaryNameNode的工作机制
快照和编辑日志的合并
SecondaryNameNode定期从Namenode获取fsimage和edits文件。fsimage是文件系统的快照,包含了文件和目录的元数据信息,而edits文件包含了最近的文件系统变更操作(例如,文件的写入、删除等)。SecondaryNameNode将fsimage和edits合并,得到一个包含最新元数据的镜像文件。
镜像文件的传输
合并后的镜像文件会通过网络传输到Namenode,并替换原有的fsimage和edits文件。这样,Namenode的元数据信息就得到了更新和持久化。
Checkpoint机制
SecondaryNameNode的这个操作被称为Checkpoint,它的频率可以通过配置文件进行调整,默认是1小时进行一次。Checkpoint后,Namenode的内存中的元数据就得到了更新,从而减少了内存中元数据的大小和内存压力。
◆NameNode和Secondary的工作流程
NameNode启动
1. 第一次启动NameNode格式化后,创建Fsimage和Edits文件。如果不是第一次启动,加载编辑日志和镜像文件到内存。
2. 客户端对元数据进行增删改的请求。
3. NameNode记录操作日志,更新滚动日志。
4. NameNode在内存中对数据进行增删改。
Secondary NameNode工作
1. SecondaryNameNode询问NameNode是否需要CheckPoint。并带回结果。
2. SecondaryNameNode请求执行CheckPoint。
3. NameNode滚动正在写的Edits_inprogress。再生成一个新的edits,之后的操作就记录在新的edits_log当中
4. 将保存的edits文件和当前的FSImage拷贝到SecondaryNameNode。
5. SecondaryNameNode加载编辑日志和镜像文件到内存,并合并。
6. 生成新的镜像文件fsimage.chkpoint。
7. 拷贝fsimage.chkpoint到NameNode。
8. NameNode将fsimage.chkpoint保存作为最新的快照。