大数据中HDFS、MapReduce、Hbase常见工作执行流程总结
1. HDFS的写流程
写数据的宏观实现流程
- 客户端向HDFS发送写数据的请求
- hdfs dfs -put tomcat.tar.gz /yjx/
- filesystem通过RPC调用NameNode的create方法
- NN首先检查是否有足够的空间权限等条件创建这个文件,同时判断这个路径是否已存在
- 有权限
- NN会针对这个文件创建一个空的Entry对象用来存储文件与Block块之间的映射关系,Block块与DN之间的映射关系
- Entry对象是一个Map对象,其中存储着文件与Block块之间的KV关系和Block块与DN之间的KV关系
- 无权限
- 直接抛出相应的异常,给予客户端错误的信息
- DFS如果接收到成功状态,会创建一个对象FSDataOutputStream给客户端使用
- 客户端需要向NN询问第一个Block存放的位置
- NN是通过机架感知策略来确定Block的存放位置(node1 node 2 node8)
- 客户端和DN节点直接建立连接
- pipeline(管道)
- 客户端和node1建立连接socket
- node1和node2创建连接 socket
- node2和node8创建连接 socket
- 客户端将文件按照块Block切分数据,但是按照packet发送数据
- 默认一个packet的大小为64k,Block大小为128M,是2048个packet
- 客户端通过pipeline管道开始使用FSDataOutputStream对象将数据输出
- 客户端首先将一个packet发送给node1,同时给予node1一个ack状态
- ACK (Acknowledge character)即是确认字符,在数据通信中,接收站发给发送站的一种传输类控制字符。表示发来的数据已确认接收无误
- node1接受数据后会将数据继续传递给node2,同时给予node2一个ack状态
- node2接受数据后会将数据继续传递给node8,同时给予node8一个ack状态
- node8将这个packet接受完成后,会响应这个ack给node2为true
- node2会响应给node1 ,同理node1响应给客户端
- 客户端接收到成功的状态,就认为某个packet发送成功了,直到当前Block块的所有packet都发送完成
- 如果客户端接收到最后一个packet的成功状态,说明当前Block传输完成,管道就会被撤销
- 客户端会将这个消息传递给NN,NN确认传输完成
- NN这时会将Block的信息记录到Entry,客户端会继续向NN询问第二个Block块的存储位置,以此类推
- block1 (node1 node2 node8)
- block2 (node1 node8 node9)
- …
- blockn(node1 node7 node9)
- 当所有的Block传输完成后,NN在Entry中存储所有的File和Block块的映射关系,以及Block块与DN的映射关系,同时关闭FSDataOutPutStream
2.HDFS的读流程
- 首先客户端发送请求到DFS,申请读取某一个文件
- hdfs dfs -get /yjx/tomcat.tar.gz
- DFS去NN查找这个文件的信息(权限,文件是否存在)
- 如果文件不存在,抛出指定的错误
- 如果文件存在,返回成功状态
- DFS创建FSDataInputStream对象,客户端通过这个对象读取数据
- 客户端获取文件第一个Block块信息,返回DN1,DN2,DN8
- 客户端直接就近原则选择DN1对应的数据即可
- 以此类推读取到其他块的信息,直到最后一个块,然后将所有的Block块合并成一个文件
- 关闭FSDataInputStream
3.Yarn 的资源调度流程
自我理解步骤:
- 首先客户端向HDFS发来一个请求,这个请求经过yarn之后被分配给RM(ResourceManager)这个资源协调框架的管理者,然后由RM来向下面的NM(NodeManager)来完成相应的请求
- 接受请求之后,RM会创建一个ApplicationMaster进程来给告诉他要完成哪些请求
- 然后ApplicationMaster会检查NodeManager下面的资源情况,查看谁有空闲的Container,接着给这些Container的NodeManager资源协调框架的执行者发出一个指令,告诉他们去给他们下面的Container去执行实际的请求
- 当Container完成了NodeManager发来的请求时,MR会杀死ApplicationMaster这个进程,然后资源被释放,请求完成
书籍借鉴步骤:
在yarn框架中执行一个MapReduce程序时,从提交到完成需要经历如下8个步骤
- 用户编写客户端应用程序,向yarn提交应用程序,提交的内容包括ApplicationMaster程序、启动ApplicationMaster的命令、用户程序等。
- yarn中的ResourceManager负责接收和处理来自客户端的请求,然后ResourceManager里面的调度器会为应用程序分配一个容器Container。同时。ResourceManager的应用程序管理器会与该容器所在的NodeManager通信,为该应用程序在该容器中启动一个ApplicationMaster
- ApplicationMaster被RM创建后,首先会向ResourceManager注册,从而使得用户可以通过ResourceManager来直接查看应用程序的运行状态,接下来的4-7步骤是具体的应用程序的执行过程
- ApplicationMaster采用轮询的方式用过RPC协议向ResourceManager申请资源
- ResourceManager以“容器”的形式向提出申请的ApplicationMaster分配资源,一旦ApplicationMaster申请到资源,就会与该容器所在的NodeManager进行通信,要求他启动任务。
- 当ApplicationMaster要求启动任务时,他会为任务设置好运行环境(包括环境变量,jar包等),然后将任务启动命令写到一个脚本中,最后通过在容器中运行该脚本来启动任务
- 各个任务通过某个RPC协议向ApplicationMaster汇报自己的进度和状态,让ApplicationMaster可以随时掌握各个任务的运行状态,从而可以在任务失败时重启任务
- 应用程序完成后,ApplicationMaster向ResourceManager的应用程序管理器注销并关闭自己,若ApplicationMaster因故障失败,ResourceManager中的应用程序管理器会检测到失败的情形,然后将其重新启动,直到所有的任务执行完毕。
4.MapReduce的工作流程 ☕️
- 客户端将每个block块切片(逻辑切分),每个切片都对应一个map任务,默认一个block块对应一个切片和一个map任务,split包含的信息:分片的元数据信息,包含起始位置,长度,和所在节点列表等。
- map按行读取切片数据,组成键值对,key为当前行在源文件中的字节偏移量,value为读到的字符串
- map函数对键值对进行计算,输出<key,value,partition(分区号)>格式数据,partition指定该键值对由哪个reducer进行处理。通过分区器,key的hashcode对reducer个数取模。
- map将kvp写入环形缓冲区内,环形缓冲区默认为100MB,阈值为80%,当环形缓冲区达到80%时,就向磁盘溢写小文件,
- 该小文件先按照分区号排序,区号相同的再按照key进行排序,归并排序。溢写的小文件如果达到三个,则进行归并,归并为大文件,大文件也按照分区和key进行排序,目的是降低中间结果数据量(网络传输),提升运行效率
- 如果map任务处理完毕,则reducer发送http get请求到map主机上下载数据,该过程被称为洗牌shuffle
- 可以设置combinclass(需要算法满足结合律),先在map端对数据进行一个压缩,再进行传输,map任务结束,reduce任务开始
- reduce会对洗牌获取的数据进行归并,如果有时间,会将归并好的数据落入磁盘(其他数据还在洗牌状态)
- 每个分区对应一个reduce,每个reduce按照key进行分组,每个分组调用一次reduce方法,该方法迭代计算,将结果写到hdfs输出
5.HBase读取数据流程
先是一个公共的流程(寻地址流程)
- Client访问Zookeeper,获取hbase:meta所在的RegionServer的节点信息
- Client访问hbase:meta所在的RegionServer,获取hbase:meta记录的元数据后先加载到内存中,然后再从内存中根据需要查询的RowKey来查询出RowKey所在的Region的相关信息(Region在RegionServer中)
- Client访问RowKey所在的RegionServer,发起数据读取请求
- RegionServer构建RegionScanner,用于对该Region的数据检索
- 需要查询的RowKey分布在多少个Region中就需要构建多少个RegionScanner
- RegionScanner构建StoreScanner,用于对该列族的数据检索
- Region中有多少个Store就需要构建多少个StoreScanner,Store的数量取决于Table的ColumnFamily的数量
- 多个StoreScanner合并构建最小堆(已排序的完全二叉树)StoreHeap:PriorityQueue
- StoreScanner构建一个MemStoreScanner和一个或多个StoreFileScanner(数量取决于StoreFile的数量)
- 过滤掉某些能够确定要查询的RowKey一定不在StoreFile内对于的StoreFileScanner或MEMStoreScanner
- 经过筛选后留下的Scanner开始做读取数据的准备,将对应的StoreFile定位到满足RowKey的起始位置
- 将所有的StoreFileScanner和MemStoreScanner合并构建最小堆
- KeyValueHeap:PriorityQueue,排序的规则按照KeyValue从小到大排序
- 从KeyValueHeap:PriorityQueue中经过一系列筛选后一行行的得到需要查询的KeyValue。
6.HBase写入数据流程
版本一:
- 首先访问Zookeeper,获取hbase:meta表位于哪个RegionServer中
- 访问对应的RegionServer,获取hbase:meta表,将其缓存到连接中,作为连接属性MetaCache,由于meta表具有一定的数据量,导致了创建连接比较慢
- 之后使用创建的连接获取Table,这是一个轻量级的连接,只有在第一次创建连接的时候会检查表格是否存在访问RegionServer,之后再获取Table时不会访问RegionServer
- 调用Table的put方法写入数据,此时还需要解析RowKey,对照缓存的MetaCache,查看具体写入的位置有哪个REgionServer
- 将数据顺序写入(追加)到WAL,此处日志的写入是直接写到HDFS上,并设置专门的线程控制WAL预写日志的滚动(类似于Flume)
- 根据写入命令的RowKey和Column Family查看具体写入到哪个Memstore,并且在MemStore中排序
- 向客户端发送ack
- 等达到MemStore的刷写时机后,将数据写到对应的Store中
版本二:
- 首先客户端和RegionServer建立连接
- 然后将DML要做的操作写入到日志wa-log中
- 将数据的修改更新到memstore中,本次的操作介绍
- 一个region由多个store组成,一个store对应一个CF(列族),store包括位于内存中的memstore和位于磁盘中的StoreFile,写操作先写入memstore
- 当memstore数据写到阈值之后,创建一个新的memstore
- 旧的memstore写成一个独立的StoreFile,RegionServer会启动flashcache进程写入StoreFile,每次写入形成单独的一个StoreFile,存放到HDFS上⛔️
- 当StoreFile文件的数量增长到一定阈值后,系统会进行合
- minor compaction
- major compaction
- 在合并的过程中会进行版本合并和删除工作,形成更大的StoreFile
- 当一个region所有StoreFile的大小和数量超过一定阈值后,会把当前的region分割成两个,并由HMaster分配到相应的RegionServer服务器,实现负载均衡
- Store负载管理当前列族的数据
- Store=1 memstore+n storefile
- 当我们进行数据DML的时候,以插入数据为例
- 我们会将数据先存到memstore中,当memstore达到阈值(128M)时
- 首先我们会创建一个新的memstore
- 然后会将memstore中的数据写成一个StoreFile,然后StoreFile会存储到HDFS上
- 随着时间的推移,数据会进行合并
- HFile中会存放大量的失效数据(删除、修改)
- 会产生多个HFile
- 等达到阈值(时间、数量)会进行合并
- 多个HFile会合并成一个大的HFile
- 合并会触发连锁反应,相邻的store也会进行合并
- 在Hbase中,表被分割成多个更小的块然后分散的存储在不同的服务器上,这些小块叫做Regions,存放Regions的地方叫做RegionServer。Master进程负责处理不同的RegionServe之间的Region的分发。在Hbase实现中HRegionServer和HRegion类代表RegionServer和Region。HRegionServer除了包含一些HRegions之外,还处理两种类型的文件用于数据存储
- HLog 预写日志文件,也叫做WAL(write-ahead log)
- HFile 是HDFS中真实存在的数据存储文件
创作整理不易,如果对你有帮助,希望能得到您的点赞或者关注,持续分享一些大数据的基础知识!