一:HDFS各个模块职责?
1.HDFS Client: 系统使用者,调用HDFS API操作文件;与NN交互获取文件元数据;与DN交互进行数据读写, 写数据时文件切分由Client完成。
2.Namenode:Master节点(也称元数据节点),是系统唯一的管理者。负责元数据的管理(名称空间和数据块映射信息);配置副本策略;处理客户端请求。
3.Datanode:数据存储节点(也称Slave节点),存储实际的数据;执行数据块的读写;汇报存储信息给NN。
4.Standby NameNode:NameNode的热备;定期合并fsimage和fsedits推送给NameNode;当Active NameNode 出现故障时,快速切换为新的 Active NameNode。
二:HDFS读文件流程?
1.使用HDFS提供的客户端开发库Client,向远程的Namenode发起RPC请求。
3.客户端会选取离客户端最接近的DataNode来读取block,如果客户端本身就是DataNode,那么将从本地直接获取数据。
4.读取完当前block的数据后,关闭与当前的DataNode连接,并为读取下一个block寻找较佳的DataNode。
5.当读完列表的block后,且文件读取还没有结束,客户端开发库会继续向Namenode获取下一批的block列表。
6.读取完一个block都会进行checksum验证,如果读取datanode时出现错误,客户端会通知Namenode,然后再从下一个拥有该block拷贝的datanode继续读。
三:HDFS写文件流程?
1.使用HDFS提供的客户端开发库Client,向远程的Namenode发起RPC请求;
2.Namenode会检查要创建的文件是否已经存在,创建者是否有权限进行操作,成功则会为文件创建一个记录,否则会让客户端抛出异常;
3.当客户端开始写入文件的时候,会将字节流数据缓存到内部的缓冲区中,当长度满足一个Chunk大小(512B)时,便会创建一个Packet对象,然后向该Packet对象中写Chunk Checksum校验和数据,以及实际数据块Chunk Data,校验和数据是基于实际数据块计算得到的。每次满足一个Chunk大小时,都会向Packet中写上述数据内容,直到达到一个Packet对象大小(64K),就会将该Packet对象放入到dataQueue队列中,等待DataStreamer线程取出并发送到DataNode节点。这时也向Namenode申请新的blocks,获取用来存储replicas的合适的datanodes列表,列表的大小根据在Namenode中对replication的设置而定。
4.开始以pipeline(管道)的形式将packet写入所有的replicas中。把packet以流的方式写入第一个datanode,该datanode把该packet存储之后,再将其传递给在此pipeline中的下一个datanode,直到最后一个datanode,这种写数据的方式呈流水线的形式。
5.最后一个datanode成功存储之后会返回一个ack packet,在pipeline里传递至客户端,在客户端的开发库内部维护着ack queue,成功收到datanode返回的ack packet后会从ack queue移除相应的packet。
6.如果传输过程中,有某个datanode出现了故障,那么当前的pipeline会被关闭,出现故障的datanode会从当前的pipeline中移除,剩余的block会继续剩下的datanode中继续以pipeline的形式传输,同时Namenode会分配一个新的datanode,保持replicas设定的数量。
四:HDFS副本放置策略?
系统默认为每一个数据块存放3个副本,按照布署在NameNode上的默认机架感知策略存放数据块副本。
第一个block副本放在,如果写请求方所在机器是其中一个datanode,则直接存放在本地,否则随机在集群中选择一个datanode。
第二个block副本放置在第二个副本存放于不同第一个副本的所在的机架。
第三个block副本放置在第二个副本所在的机架,但是属于不同的节点。
五:HDFS如何保证HA?
1.QJM/Qurom Journal Manager
这是一个基于Paxos算法实现的HDFS HA方案,基本原理就是用2N+1台 JournalNode存储EditLog,每次写数据操作有大多数(>=N+1)返回成功时即认为该次写成功,数据不会丢失了。当然这个算法所能容忍的是最多有N台机器挂掉,如果多于N台挂掉,这个算法就失效了。这个原理是基于Paxos算法,在HA架构里面SecondaryNameNode这个冷备角色已经不存在了,为了保持standby NN时时的与主Active NN的元数据保持一致,他们之间交互通过一系列守护的轻量级进程JournalNode,任何修改操作在 Active NN上执行时,JN进程同时也会记录修改log到至少半数以上的JN中,这时 Standby NN 监测到JN里面的同步log发生变化了会读取 JN 里面的修改log,然后同步到自己的的目录镜像树里面。当发生故障时,Active的 NN 挂掉后,Standby NN 会在它成为Active NN 前,读取所有的JN里面的修改日志,这样就能高可靠的保证与挂掉的NN的目录镜像树一致,然后无缝的接替它的职责,维护来自客户端请求,从而达到一个高可用的目的。
2.Fencing
Datanode的fencing:确保只有一个NN能命令DN。HDFS-1972中详细描述了DN如何实现fencing。每个NN改变状态的时候,向DN发送自己的状态和一个序列号;DN在运行过程中维护此序列号,当failover时,新的NN在返回DN心跳时会返回自己的active状态和一个更大的序列号,DN接收到这个返回则认为该NN为新的active;如果这时原来的active NN恢复,返回给DN的心跳信息包含active状态和原来的序列号,这时DN就会拒绝这个NN的命令;
客户端的fencing:确保只有一个NN能响应客户端请求,让访问standby nn的客户端直接失败。在RPC层封装了一层,通过FailoverProxyProvider以重试的方式连接NN。通过若干次连接一个NN失败后尝试连接新的NN,对客户端的影响是重试的时候增加一定的延迟,客户端可以设置重试次数和时间。Hadoop提供了ZKFailoverController角色,部署在每个NameNode的节点上,作为一个deamon进程, 简称zkfc。FailoverController主要包括三个组件,HealthMonitor: 监控NameNode是否处于unavailable或unhealthy状态,当前通过RPC调用NN相应的方法完成;ActiveStandbyElector:管理和监控自己在ZK中的状态;ZKFailoverController它订阅HealthMonitor 和ActiveStandbyElector 的事件,并管理NameNode的状态。
ZKFailoverController主要职责:
健康监测:周期性的向它监控的NN发送健康探测命令,从而来确定某个NameNode是否处于健康状态,如果机器宕机,心跳失败,那么zkfc就会标记它处于一个不健康的状态
会话管理:如果NN是健康的,zkfc就会在zookeeper中保持一个打开的会话,如果NameNode同时还是Active状态的,那么zkfc还会在Zookeeper中占有一个类型为短暂类型的znode,当这个NN挂掉时,这个znode将会被删除,然后备用的NN,将会得到这把锁,升级为主NN,同时标记状态为Active。当宕机的NN新启动时,它会再次注册zookeper,发现已经有znode锁了,便会自动变为Standby状态,如此往复循环,保证高可靠,需要注意,目前仅仅支持最多配置2个NN。
master选举:如上所述,通过在zookeeper中维持一个短暂类型的znode,来实现抢占式的锁机制,从而判断那个NameNode为Active状态。
3.Federation
多个NN共用一个集群里的存储资源,每个NN都可以单独对外提供服务;每个NN都会定义一个存储池,有单独的id,每个DN都为所有存储池提供存储;DN会按照存储池id向其对应的NN汇报块信息,同时DN会向所有NN汇报本地存储可用资源情况;如果需要在客户端方便的访问若干个NN上的资源,可以使用客户端挂载表,把不同的目录映射到不同的NN,但NN上必须存在相应的目录。
六:HDFS机架感知策略?
通常,大型 Hadoop 集群是以机架的形式来组织的,同一个机架上不同 节点间的网络状况比不同机架之间的更为理想。 另外, NameNode 设法将数据块副本保存在不同的机架上以提高容错性。
而 HDFS 不能够自动判断集群中各个 datanode 的网络拓扑情况 Hadoop 允许集群的管理员通过配置 dfs.network.script 参数来确定节点所处的机架。 文件提供了 IP->rackid 的翻译。NameNode通过这个得到集群中各个 datanode机器的 rackid。如果 topology.script.file.name 没有设定,则每个 IP 都会翻译成/default-rack 。
distance(/D1/R1/H1,/D2/R3/H7)=6 不同 IDC 下的 datanode
七:HDFS如何进行权限控制?
1.默认ACL必须包含所有最小要求的ACL项,包括文件拥有者项,文件所属的组项和其它用户项即:
2.每个ACL项由类型,可选的名称和权限字符串组成,它们之间使用冒号":"。这组ACL访问列表中,文件的拥有者具有读写权限,文件所属的组具有读和执行的权限,其他用户具有读权限;除此之外,还有两个扩展的ACL项,分别为用户bruce和组sales,并都授予了读写执行的权限。
3.默认访问控制列表:有目录可能拥有默认访问控制列表,当创建新文件或者子目录时,自动拷贝父辈的默认访问控制列表到自己的访问控制列表中,新的子目录也拷贝父辈默认的访问控制列表到自己的默认访问控制列表中。这样,当创建子目录时默认ACL将沿着文件系统树被任意深层次地拷贝。
参考文献
1.http://f.dataguru.cn/thread-24868-1-1.html
2.http://www.cnblogs.com/tgzhu/p/5788634.html
3.http://shiyanjun.cn/archives/942.html
4.http://blog.csdn.net/sudaxhh/article/details/52334652
5.http://blog.csdn.net/tantexian/article/details/44964587
6.http://www.cnblogs.com/tgzhu/p/5788634.html