【关于Hadoop】
生态系统
![image image]()
【关于HDFS】
【hdfs架构】
分布式文件系统
流式数据访问:一次写入,多次读取。只支持单个写入者,写操作总是以“只添加”的方式在文件末尾写数据
采用Master/Slave架构来存储数据,主要由四部分组成:Client、NameNode、DataNode和Secondary NameNode
关键组件有两个:【NameNode、DataNode】
Client:
1.文件上传HDFS,将文件切分成一个个block
2.与NN交互,获取文件的位置信息
3.与DN交互,读取或者写入数据
4.提供命令来管理访问HDFS
*NameNode:就是master,元数据管理
1.管理文件系统的命名空间,维护文件系统树
2.管理block的映射信息
3.配置副本策略
4.处理客户端的读写操作
*DataNode:就是Slave
1.存储实际的数据块
2.执行数据块的读写操作
Secondary NameNode:并非备份,是辅助
1.辅助NN,分担工作量
2.定期合并fsimage和edits,并推送给NN
【fsimage】命名空间镜像文件
【edits】编辑日志文件
【hdfs读取流程】
1.客户端调用FileSystem对象的open()方法来打开希望读取的文件,
获取的其实是一个distributedFileSystem实例
2.distributedFileSystem通过远程过程调用(RPC)来调用NN,来确认文件的起始块的位置,NN返回的是该块副本的DN地址,这些DN会根据与客户端的距离来排序,距离客户端近的排在前面
3.前两步将返回一个FSDataInputStream对象,这个对象会被封装成DFSInputStream对象,这个对象可以方便的管理DN和NN的数据流,客户端调用这个类的read方法,DFSInputStream就会找出离客户端最近的DN并连接DN
4.数据从DN源源不断的流向客户端
5.如果第一个block块读完了,就会关闭指向第一个block块的DN连接,接着读取下一个block块。
6.第一批读完,DFSInputStream就会去NN拿下一批的块的地址,读完所有就关闭
![image image]()
【hdfs写入流程】
1.客户端通过调用DistributedFileSystem 的create方法,创建一个新的文件。
2.DistributedFileSystem 通过 RPC(远程过程调用)调用 NN,去创建一个没有blocks关联的新文件。创建前,NN 会做各种校验,比如文件是否存在,客户端有无权限去创建等。如果校验通过,NN就会记录下新文件,否则就会抛出IO异常。
3.前两步结束后会返回 FSDataOutputStream 的对象,和读文件的时候相似,FSDataOutputStream 被封装成 DFSOutputStream,DFSOutputStream 可以协调 NN和 DN。客户端开始写数据到DFSOutputStream,DFSOutputStream会把数据切成一个个小packet,然后排成队列 data queue。
4.DataStreamer 会去处理接受 data queue,它先问询 NN 这个新的 block 最适合存储的在哪几个DN里,比如重复数是3,那么就找到3个最适合的 DN,把它们排成一个 pipeline。DataStreamer 把 packet 按队列输出到管道的第一个 DN 中,第一个 DN又把 packet 输出到第二个DN中,以此类推。
5.DFSOutputStream 还有一个队列叫 ack queue,也是由 packet 组成,等待DN的收到响应,当pipeline中的所有DN都表示已经收到的时候,这时akc queue才会把对应的packet包移除掉。
6.客户端完成写数据后,调用close方法关闭写入流。
7.DataStreamer 把剩余的包都刷到 pipeline 里,然后等待 ack 信息,收到最后一个 ack 后,通知 DN 把文件标示为已完成。
![image image]()
【关于MapReduce】
流程
![image image]()
1.在客户端启动一个作业。
【编写mapreduce程序,配置作业,提交作业,这是程序员的工作】
2.向JobTracker请求一个Job ID,就像你排队买车一样,拿到摇号- -
【 JobTracker是一个后台服务进程,启动之后,会一直监听并接收来自各个TaskTracker发送的心跳信息,包括资源使用情况和任务运行情况等信息。】
作业控制:在hadoop中每个应用程序被表示成一个作业,每个作业又被分成多个任务,JobTracker的作业控制模块则负责作业的分解和状态监控。
状态监控:主要包括TaskTracker状态监控、作业状态监控和任务状态监控。主要作用:容错和为任务调度提供决策依据。
JobTracker只有一个,他负责了任务的信息采集整理,你就把它当做包工头把,这个和采用Master/Slave结构中的Master保持一致
JobTracker 对应于 NameNode
一般情况应该把JobTracker部署在单独的机器上
3.将运行作业所需要的资源文件复制到HDFS上,包括MapReduce程序打包的JAR文件、配置文件和客户端计算所得的输入划分信息。这些文件都存放在JobTracker专门为该作业创建的文件夹中。文件夹名为该作业的Job ID。JAR文件默认会有10个副本(mapred.submit.replication属性控制);输入划分信息(Split)告诉了JobTracker应该为这个作业启动多少个map任务等信息。
4.JobTracker接收到作业后,将其放在一个作业队列里(一般来说,公司部门都与自己的队列,默认的调度方法是FIFO,也就是first in first out-队列),等待作业调度器对其进行调度,当作业调度器根据自己的调度算法调度到该作业时,会根据输入划分信息(Split)为每个划分创建一个map任务,并将map任务分配给TaskTracker执行。对于map和reduce任务,TaskTracker根据主机核的数量和内存的大小有固定数量的map槽和reduce槽。这里需要强调的是:map任务不是随随便便地分配给某个TaskTracker的,这里有个概念叫:数据本地化(Data-Local)。意思是:将map任务分配给含有该map处理的数据块的TaskTracker上,同时将程序JAR包复制到该TaskTracker上来运行,这叫“运算移动,数据不移动”。而分配reduce任务时并不考虑数据本地化。
5.TaskTracker每隔一段时间会给JobTracker发送一个心跳,告诉JobTracker它依然在运行,同时心跳中还携带着很多的信息,比如当前map任务完成的进度等信息。当JobTracker收到作业的最后一个任务完成信息时,便把该作业设置成“成功”。当JobClient查询状态时,它将得知任务已完成,便显示一条消息给用户。
【从map和reduce层次分析】
![image image]()
input:也就是数据存储位置,这里当然是类似于hdfs这样的分布式存储
split:因为map task只读split,而split基本上和hdfs的基本存储块block同样大小,一个split对应一个map,你可以把它当做map的单位块来理解,投喂进map的时候必须要这样的格式,打个比方,比如只收硬币的地铁站,你只能投放1元硬币
map:拆解
每个map对应一个split,生成key/value键值对
【shuffle】:核心,对map输出的结果进行 分区 排序 合并 等处理并交给Reduce的过程。
(1)在map端,map的结果首先被写入缓存,当缓存满了,将缓存的数据进行分区,然后对每个分区的数据排序和合并,之后写入磁盘文件。每次缓存满了溢出就会生成一个磁盘文件,在map任务全部结束之前,这个溢写文件归并成一个大的文件,然后通知reduce任务来领取处理。
![image image]()
(2)在reduce端,通过RPC向JobTracker询问Map任务是否完成,若完成则领取数据,领取的数据来自不同的map机器,先归并后合并
reduce:把每个文件的内容最后统计一次
【结合Wordcount,再来分析下流程】
1--创建两个文本文件,作为输入
![image image]()
2--Map
拆解,两个文件的输入默认就是两个split,默认交由两个mapper处理
文件内容被分解为 单词 和 1 ,单词是key 主键 后面的数字就是 value
![image image]()
3--partition【shuffle之一】
分区;按照key的不同,把数据分开,key不能身处两个节点上,所以经常使用哈希来分区
![image image]()
![image image]()
分区是为后面的reduce做准备
4--sort【shuffle之一】
排序;
![image image]()
![image image]()
5--combine【shuffle之一】
结合;先进行一次计算,减少文件大小,不必须
![image image]()
![image image]()
6--copy【shuffle之一】!将不同文件的相似部分分给一个reduce
通过http方式,由reduce节点向各mapper节点下载属于自己分区的数据。
7--merge【shuffle之一】
把分区的文件合并成一个文件
![image image]()
8--reduce
![image image]()
【关于yarn】
【yarn架构】
集群资源管理系统
改善mapreduce的实现,还可以支持其他的分布式计算模式
存在最大的问题就是资源管理和任务管理耦合在一起,且整个集群的扩展性、可靠性(JobTracker的单节点故障问题)很差,以及最重要的一个问题,集群资源的利用率低。随着数据规模的膨胀,大家已经不满足于仅仅能在Hadoop集群上运行MapReduce程序,更希望能够有一套合理的管理机制来控制整个集群的资源调度,于是Yarn平台应运而生。先来看看Yarn平台的基本架构:
![image image]()
在Yarn的结构中,把原来JobTracker管的事儿(资源管理、任务调度)拆开了,资源调度让ResourceManager干,任务调度让 ApplicationMaster管
![image image]()
【ResourceManager】
整个Yarn架构的核心部件,有且仅有一个,它负责整个集群的资源(内存、cpu等)管理,RM主要处理6中事件:1.集群中被移除一个计算节点;2.增加了一个计算节点;3.收到一个新的Application;4.一个Application运行结束;5.container闲置;6.心跳机制向ResourceManager汇报各个container运行情况,由于此时可能有新的 container得到释放,因此该事件会触发资源分配,也就是说,该事件是6个事件中最重要的事件,它会触发资源调度器最核心的资源分配机制。
【ApplicationMaster】
ApplicationMaster 负责管理应用程序的整个生命周期,每个应用程序都对应一个AM,主要功能有:
(1) 与RM的调度器通讯,协商管理资源分配。
(2) 与NM合作,在合适的容器中运行对应的task,并监控这些task执行。
(3) 如果container出现故障,AM会重新向调度器申请资源。
(4) 计算应用程序所需的资源量,并转化成调度器可识别的协议。
(5) AM出现故障后,ASM会重启它,而由AM自己从之前保存的应用程序执行状态中恢复应用程序。
【NodeManager】
NodeManager替代了Hadoop v1版本中的TaskTracker,每个节点都会有一个NM,主要功能有:
(1) 为应用程序启动容器,同时确保申请的容器使用的资源不会超过节点上的总资源。
(2) 为task构建容器环境,包括二进制可执行文件,jars等。
(3) 为所在的节点提供了一个管理本地存储资源的简单服务,应用程序可以继续使用本地存储资源即使他没有从RM那申请。比如:MapReduce可以使用该服务程序存储map task的中间输出结果。
一个NodeManager上面可以运行多个Container,Container之间的资源互相隔离,类似于虚拟机的多个系统一样,各 自使用自己分配的资源。NodeManager会启动一个监控进行用来对运行在它上面的Container进行监控,当某个Container占用的资源 超过约定的阈值后,NodeManager就会将其杀死。
【Container】
Container可以说是一个对Application使用资源描述的集合(或容器),可以看做一个可序列化的java对象,封装了一些描述信息,例如:![image image]()
(1) Container是YARN中资源的抽象,它封装了某个节点上一定量的资源(CPU和内存两类资源)。它跟Linux Container没有任何关系,仅仅是YARN提出的一个概念(从实现上看,可看做一个可序列化/反序列化的Java类)。
(2) Container由ApplicationMaster向ResourceManager申请的,由ResouceManager中的资源调度器异步分配给ApplicationMaster;
(3) Container的运行是由ApplicationMaster向资源所在的NodeManager发起的,Container运行时需提供内部执行的 任务命令(可以使任何命令,比如java、Python、C++进程启动命令均可)以及该命令执行所需的环境变量和外部资源(比如词典文件、可执行文件、 jar包等)。
【通信过程】
YARN通信协议,RPC协议是连接各个组件的“大动脉”,了解不同组件之间的RPC协议有助于我们更深入地学习YARN框架。在YARN中,任何两个需相互通信的组件之间仅有一个RPC协议,而对于任何一个RPC协议,通信双方有一端是Client,另一端为Server,且Client总是主动连接Server的,因此,YARN实际上采用的是拉式(pull-based)通信模型。如图2-10所示,箭头指向的组件是RPC Server,而箭头尾部的组件是RPC Client,YARN主要由以下几个RPC协议组成:
JobClient(作业提交客户端)与RM之间的协议—ApplicationClientProtocol:JobClient通过该RPC协议提交应用程序、查询应用程序状态等。
Admin(管理员)与RM之间的通信协议—ResourceManagerAdministrationProtocol:Admin通过该RPC协议更新系统配置文件,比如节点黑白名单、用户队列权限等。
AM与RM之间的协议—ApplicationMasterProtocol:AM通过该RPC协议向RM注册和撤销自己,并为各个任务申请资源。
AM与NM之间的协议—ContainerManagementProtocol:AM通过该RPC要求NM启动或者停止Container,获取各个Container的使用状态等信息。
NM与RM之间的协议—ResourceTracker:NM通过该RPC协议向RM注册,并定时发送心跳信息汇报当前节点的资源使用情况和Container运行情况。