Hadoop之HDFS前端
版权声明:本文为yunshuxueyuan原创文章。
如需转载请标明出处: http://www.cnblogs.com/sxt-zkys/
QQ技术交流群:299142667node
HDFS介绍算法
HDFS(Hadoop Distributed File System )Hadoop分布式文件系统。是根据google发表的论文翻版的。数据库
什么是分布式文件系统服务器
分布式文件系统(Distributed File System)是指文件系统管理的物理存储资源不必定直接链接在本地节点上,而是经过计算机网络与节点相连。分布式文件系统的设计基于客户机/服务器模式。网络
[优势]session
支持超大文件 超大文件在这里指的是几百M,几百GB,甚至几TB大小的文件。架构
检测和快速应对硬件故障在集群的环境中,硬件故障是常见的问题。由于有上千台服务器链接在一块儿,这样会致使高故障率。所以故障检测和自动恢复是hdfs文件系统的一个设计目标运维
流式数据访问应用程序能以流的形式访问数据集。主要的是数据的吞吐量,而不是访问速度。socket
简化的一致性模型 大部分hdfs操做文件时,须要一次写入,屡次读取。在hdfs中,一个文件一旦通过建立、写入、关闭后,通常就不须要修改了。这样简单的一致性模型,有利于提升吞吐量。
[缺点]
低延迟数据访问如和用户进行交互的应用,须要数据在毫秒或秒的范围内获得响应。因为hadoop针对高数据吞吐量作了优化,牺牲了获取数据的延迟,因此对于低延迟来讲,不适合用hadoop来作。
大量的小文件Hdfs支持超大的文件,是经过数据分布在数据节点,数据的元数据保存在名字节点上。名字节点的内存大小,决定了hdfs文件系统可保存的文件数量。虽然如今的系统内存都比较大,但大量的小文件仍是会影响名字节点的性能。
多用户写入文件、修改文件Hdfs的文件只能有一次写入,不支持写入,也不支持修改。只有这样数据的吞吐量才能大。
不支持超强的事务没有像关系型数据库那样,对事务有强有力的支持。
[HDFS结构]
NameNode:分布式文件系统中的管理者,主要负责管理文件系统的命名空间、集群配置信息和存储块的复制等。NameNode会将文件系统的Meta-data存储在内存中,这些信息主要包括了文件信息、每个文件对应的文件块的信息和每个文件块在DataNode的信息等。
SecondaryNameNode:合并fsimage和fsedits而后再发给namenode。
DataNode:是文件存储的基本单元,它将Block存储在本地文件系统中,保存了Block的Meta-data同时周期性地将全部存在的Block信息发送给NameNode。
Client:就是须要获取分布式文件系统文件的应用程序。
fsimage:元数据镜像文件(文件系统的目录树。)
edits:元数据的操做日志(针对文件系统作的修改操做记录)
NameNode、DataNode和Client之间通讯方式:
client和namenode之间是经过rpc通讯;
datanode和namenode之间是经过rpc通讯;
client和datanode之间是经过简单的socket通讯。
Client读取HDFS中数据的流程
1. 客户端经过调用FileSystem对象的open()方法打开但愿读取的文件。
2. DistributedFileSystem经过使用RPC来调用namenode,以肯定文件起始块的位置。[注1]
3. Client对输入流调用read()方法。
4. 存储着文件起始块的natanoe地址的DFSInputStream[注2]随即连接距离最近的datanode。经过对数据流反复调用read()方法,能够将数据从datanode传输到Client。[注3]
5. 到达快的末端时,DFSInputStream会关闭与该datanode的链接,而后寻找下一个快递最佳datanode。
6. Client读取数据是按照卡开DFSInputStream与datanode新建链接的顺序读取的。它须要询问namenode来检索下一批所须要的datanode的位置。一旦完成读取,调用FSDataInputStream调用close()方法。
[注1]:对于每个块,namenode返回存在该块副本的datanode地址。这些datanode根据他们于客户端的距离来排序,若是客户端自己就是一个datanode,并保存有响应数据块的一个副本时,该节点从本地datanode中读取数据。
[注2]:Di是tribute File System类返回一个FSDataInputStream对象给Client并读取数据。FSDataInputStream类转而封装DFSInputStream对象,该对象管理datanode和namenode的I/O。
[注3]:若是DFSInputStream在与datanode通讯时遇到错误,它便会尝试从这个块的另一个最临近datanode读取数据。它也会记住哪一个故障的natanode,以保证之后不回反复读取该节点上后续的块。DFSInputStream也会经过校验和确认从datanode发来的数据是否完整。若是发现一个损坏的块,它就会在DFSinputStream视图从其余datanode读取一个块的副本以前通知namenode。
Client将数据写入HDFS流程
1. Client调用DistributedFileSystem对象的create()方法,建立一个文件输出流
2. DistributedFileSystem对namenode建立一个RPC调用,在文件系统的命名空间中建立一个新文件。
3. Namenode执行各类不一样的检查以确保这个文件不存在,而且客户端有建立该文件的权限。若是这些检查均经过,namenode就会为建立新文件记录一条记录,不然,文件建立失败,向Client抛出IOException,DistributedFileSystem向Client返回一个FSDataOutputStream队形,Client能够开始写入数据。
4. DFSOutputStream将它分红一个个的数据包,并写入内部队列。DataStreamer处理数据队列,它的责任时根据datanode列表来要求namenode分配适合新块来存储数据备份。这一组datanode构成一个管线---咱们假设副本数为3,管路中有3个节点,DataStreamer将数据包流式床书到管线中第一个datanode,该dananode存储数据包并将它发送到管线中的第二个datanode,一样地,第二个datanode存储该数据包而且发送给管县中的第3个。
5. DFSOutputStream也维护着一个内部数据包队列来等待datanode的收到确认回执(ack queue)。当收到管道中全部datanode确认信息后,该数据包才会从确认队列删除。[注1]
6. Client完成数据的写入后,回对数据流调用close()方法
7. 将剩余全部的数据包写入datanode管线中,而且在练习namenode且发送文件写入完成信号以前。
[注1]:若是在数据写入期间,datanode发生故障,则:1.关闭管线,确认把队列中的任何数据包添加回数据队列的最前端,一去到故障节点下游的datanode不回漏包。2.为存储在另外一个正常datanode的当前数据块指定一个新的标志,并将给标志传给namenode,以便故障datanode在恢复后能够删除存储的部分数据块。3.从管线中删除故障数据节点,而且把余下的数据块写入管线中的两个正常的datanode。namenode注意到副本量不足时,会在另外一个节点上建立一个新的副本。
Hadoop中NameNode单点故障解决方案
Hadoop 1.0内核主要由两个分支组成:MapReduce和HDFS,这两个系统的设计缺陷是单点故障,即MR的JobTracker和HDFS的NameNode两个核心服务均存在单点问题,这里只讨论HDFS的NameNode单点故障的解决方案。
[问题]
HDFS仿照google GFS实现的分布式存储系统,由NameNode和DataNode两种服务组成,其中NameNode是存储了元数据信息(fsimage)和操做日志(edits),因为它是惟一的,其可用性直接决定了整个存储系统的可用性。由于客户端对HDFS的读、写操做以前都要访问name node服务器,客户端只有从name node获取元数据以后才能继续进行读、写。一旦NameNode出现故障,将影响整个存储系统的使用。
[解决方案]
Hadoop官方提供了一种quorum journal manager来实现高可用,在高可用配置下,edit log再也不存放在名称节点,而是存放在一个共享存储的地方,这个共享存储由若干Journal Node组成,通常是3个节点(JN小集群), 每一个JN专门用于存放来自NN的编辑日志,编辑日志由活跃状态的名称节点写入。
要有2个NN节点,两者之中只能有一个处于活跃状态(active),另外一个是待命状态(standby),只有active节点才能对外提供读写HDFS服务,也只有active态的NN才能向JN写入编辑日志;standby的名称节点只负责从JN小集群中的JN节点拷贝数据到本地存放。另外,各个DATA NODE也要同时向两个NameNode节点报告状态(心跳信息、块信息)。
一主一从的2个NameNode节点同时和3个JN构成的组保持通讯,活跃的NameNode节点负责往JN集群写入编辑日志,待命的NN节点负责观察JN组中的编辑日志,而且把日志拉取到待命节点(接管Secondary NameNode的工做)。再加上两节点各自的fsimage镜像文件,这样一来就能确保两个NN的元数据保持同步。一旦active不可用,standby继续对外提供服。架构分为手动模式和自动模式,其中手动模式是指由管理员经过命令进行主备切换,这一般在服务升级时有用,自动模式可下降运维成本,但存在潜在危险。这两种模式下的架构以下。
[手动模式]
模拟流程:
1. 准备3台服务器分别用于运行JournalNode进程(也能够运行在date node服务器上),准备2台namenode服务器用于运行NameNode进程(两台配置 要同样),DataNode节点数量不限。
2. 分别启动3台JN服务器上的JournalNode进程,分别在date node服务器启动DataNode进程。
3. 须要同步2台name node之间的元数据。具体作法:从第一台NN拷贝元数据到放到另外一台NN,而后启动第一台的NameNode进程,再到另外一台名称节点上作standby引导。
4. 把第一台名节点的edit日志初始化到JN节点,以供standby节点到JN节点拉取数据。
5. 启动standby状态的NameNode节点,这样就能同步fsimage文件。
6. 模拟故障,手动把active状态的NN故障,转移到另外一台NameNode。
[自动模式]
模拟流程:
在手动模式下引入了ZKFC(DFSZKFailoverController)和zookeeper集群
ZKFC主要负责: 健康监控、session管理、leader选举
zookeeper集群主要负责:服务同步
1-6步同手动模式
7. 准备3台主机安装zookeeper,3台主机造成一个小的zookeeper集群.
8. 启动ZK集群每一个节点上的QuorumPeerMain进程
9. 登陆其中一台NN, 在ZK中初始化HA状态
10. 模拟故障:停掉活跃的NameNode进程,提早配置的zookeeper会把standby节点自动变为active,继续提供服务。
脑裂
脑裂是指在主备切换时,因为切换不完全或其余缘由,致使客户端和Slave误觉得出现两个active master,最终使得整个集群处于混乱状态。解决脑裂问题,一般采用隔离(Fencing)机制。
共享存储fencing:确保只有一个Master往共享存储中写数据,使用QJM实现fencing。
Qurom Journal Manager,基于Paxos(基于消息传递的一致性算法),Paxos算法是解决分布式环境中如何就某个值达成一致。
[原理]
a. 初始化后,Active把editlog日志写到JN上,每一个editlog有一个编号,每次写editlog只要其中大多数JN返回成功(过半)即认定写成功。
b. Standby按期从JN读取一批editlog,并应用到内存中的FsImage中。
c. NameNode每次写Editlog都须要传递一个编号Epoch给JN,JN会对比Epoch,若是比本身保存的Epoch大或相同,则能够写,JN更新本身的Epoch到最新,不然拒绝操做。在切换时,Standby转换为Active时,会把Epoch+1,这样就防止即便以前的NameNode向JN写日志,也会失败。
客户端fencing:确保只有一个Master能够响应客户端的请求。
[原理]
在RPC层封装了一层,经过FailoverProxyProvider以重试的方式链接NN。经过若干次链接一个NN失败后尝试链接新的NN,对客户端的影响是重试的时候增长必定的延迟。客户端能够设置重试此时和时间
Slave fencing:确保只有一个Master能够向Slave下发命令。
[原理]
a. 每一个NN改变状态的时候,向DN发送本身的状态和一个序列号。
b. DN在运行过程当中维护此序列号,当failover时,新的NN在返回DN心跳时会返回本身的active状态和一个更大的序列号。DN接收到这个返回是认为该NN为新的active。
b. 若是这时原来的active(好比GC)恢复,返回给DN的心跳信息包含active状态和原来的序列号,这时DN就会拒绝这个NN的命令。
最后在此感谢尚学堂周老师在我学习过程当中给予的帮助。