果然欠下的帐终究还是要还回来的,之前不好好学Hadoop,现在全给补回来,看着这些既熟悉又陌生的知识点,只得静下心好好过一遍,毕竟当初也是只有期末考试之前才集中性背过,那种不结合实践操作的理论背诵是背了就忘,没法理解的。来回顾HDFS的理论部分(安装好HDFS之后再来回顾的)
一.HDFS概述
HDFS 是Hadoop项目的核心子项目,是分布式计算中数据存储管理的基础,是基于流数据模式访问和处理超大文件的需求而开发的,可以运行在廉价的商用服务器上。源于GFS,一个GFS的克隆版本。
数据量越来越大,一台服务器存储有限,所以数据应该分配到更多机器的磁盘中,因此需要一种系统来管理多台机器上的文件,就是分布式文件管理系统。高容错的特点可以是他部署在廉价的通用硬件上,提供高吞吐率的数据访问,适合那些需要处理海量数据集的应用程序。
它有以下特点:
高容错性:
1.上传数据自动保存多个副本,他是通过增加副本的数量,来增加他的容错性。
2.如果一个副本丢失,HDFS机制会复制其他机器上的副本,而我们不必关注它的实现(自动完成)
支持超大文件:
超大文件指的是几百GB甚至几个TB的文件,一般来说一个Hadoop文件系统会存储TB,PB级别的数据。
流式数据访问:
HDFS处理的数据规模都比较大,应用一次需要访问大量的数据。同时,在这些应用一般是批量处理,而不是用户交互式处理。HDFS使应用程序能够以流的形式访问数据集,注重的是数据的吞吐量,而不是访问数据的速度。
简化的一致性模型:
大部分的HDFS程序操作文件时需要一次写入,多次读取。在HDFS中,一个文件一旦经过创建、写入、关闭后,一般就不需要修改了,这样简单的一致性模型,有利于提供高吞吐量的数据访问模型。
二.HDFS系统架构
角色:Namenode 、DateNode、Client
Client 客户端可以往里面写数据,红框里就是大文件分成的一个个数据块Blocks,分散到各个节点
节点中文件在多个机器有副本,一旦一个副本丢失,会复制其他机器上的副本,高容错性。
Client (客户端)
- 实现文件切分
- 与NameNode交互,获取文件的位置信息
- 跟DataNode交互,读取对应的数据块
- 访问和访问HDFS
NameNode(Master)
- 管理Hdfs的名称空间
- 管理数据块的映射关系
- 配置副本策略
- 客户端的读写请求
DataNode(Slave)
- 存储实际的数据块
- 执行数据块的读写操作
Block(数据块)
一个文件是被切分成多个block,并且多个block有多个副本,这些副本被分布在多个Datanode上,数据块是HDFS最小存储单元。
元数据
是文件系统中文件和目录的信息以及文件和block的对应关系。
命名空间镜像(FSImage)
HDFS的目录树及文件/目录元信息是保存在内存中,如果节点掉电或进程崩溃,数据将不再存在,必须将上述信息保存到磁盘,FSImage就是保存某一时刻元数据的信息的磁盘文件。
镜像编辑日志(EditLog)
对内存目录树的修改,也必须同步到磁盘元数据上,但每次修改都将内存元数据导出到磁盘,显然是不现实的,为此namenode引入了镜像编辑日志,将每次的改动都保存在日志中,如果namenode机器宕机或者namenode进程挂掉之后可以使用FSImage和EditLog文件联合恢复内存元数据。
先发布,明天早上再写。
任务安排:下午学习新的知识点,次日早上总结学过的知识点在cdsn
三.HDFS HA(高可用)
ZKFC监控NN的健康状况
HDFS HA-Namenode HA工作原理
- 2台独立的机器的来配置NameNode角色,无论在任何时候,集群中只能有一个NameNode作为Active状态,而另一个是Standby状态。Active状态的NameNode负责集群中所有的客户端操作,状态为Standby的NalteNode这时候仅仅扮演一个Slave的角色,以便于在任何时候Active的NameNode挂掉时能够第一时间接替它的任务,成为主NameNode,达到一个热备份的效果,
- 为了保持从NameNode与主NameNode的元数据保持一致,他们之间的交互通过一系列守护的轻量级进程JournalNode来完成,当任何修改操作在主NameNode上执行时,它同时也会记录修改log到至少半数以上的JornalNode中,这时状态为Standby的NameNode监测到JournalNode里面的同步log发生变化了,会读取JornalNode里面的修改log,然后同步到自己的的目录镜像树里面
-
当发生故障时,Active的NameNode挂掉后,Standby的NameNode会在它成为Active
NameNode前,读取所有的JournalNode里面的修改日志,这样就能高可靠的保证与挂
掉的NameNode的目录镜像树一致,然后无缝的接替它的职责,维护来自客户端请求,
从而达到一个高可用的目的。 -
为了达到快速容错掌握全局的目的,Standby角色也会接受来自DataNode角色汇报的
块信息。
HDFS HA-ZKFailoverController
ZKFailoverController作为独立的进程运行,简称ZKFC,对NameNode的主备切换进行总体控制。ZKFailoverController能及时检测到NameNode的健康状况,在主NameNode故障时借助Zookeeper实现自动的主备选举和切换每个运行NameNode的机器上都会运行一个ZKFC。
(主nn挂掉之后zkfc监听到主nn的情况,通知zookeeper将主nn的active锁释放,通知从nn来上active锁)
ZKFC的作用如下:
- NameNode健康状况监控: ZKFC定期以RPC的方式向本地的NameNode发送健康检查命令,只要NameNode及时回复自己是健康的,那么ZKFC则认为NameNode是健康的。如果NameNode宕机、卡死,则ZKFC则认为NameNode是不健康的。
- ZK会话管理: 当本地的NameNode是健康的,ZKFC则以心跳的方式保持一个会话。如果本地的NameNode是Active的,ZKFC也在ZK上持有一个特殊lockznode如果ZKFC检测到NameNode时不健康的,则停止向ZK报心跳,会话失效,Locknode过期删除。
- ZK选举: 如果本地的NameNode是健康的,ZKFC也没有看到其他NameNode持有lockznode它将试着获取lockznode,如果成功,即赢得了选举,则它本地的namenode变为active。
ZKFC为什么要作为一个deamon进程从NN分离出来?
- 防止因为NN的GC失败导致心跳受影响。
- FailoverController功能的代码应该和应用的分离,提高的容错性。
- 使得主备选举成为可插拔式的插件。
HDFS HA-共享存储QJM.
NameNode记录了HDFS的目录文件等元数据,客户端每次对文件的增删改等操作,Namenode都会记录一条日志,叫做editlog, 而元数据存储在fsimage中。为了保持Stadnby与active的状态一致, standby 需要尽量实时获取每条editlog日志,并应用到Fslmage中。这时需要一个共享存储存放editlog,standby能实时获取日志。
两个关键点需要保证:
- 共享存储是高可用的。
- 需要防止两个NameNode同时向共享存储写数据导致数据损坏。共享存储常用的方式是Qurom Journal Manager ,它包含多个journalnode。
QJM 可以认为包含一些journalnode的集群,journalnode运行在不同的机器上,每个journalnode是一个很轻量的守护进程,所以可以部署在Hadoop集群节点上,QJM至少要有三个journalnode,因为edit log 必须要写到journalnodes 中大部分节点中,比如运行3,5,7个journalnode,那就最多可容忍1,2,3个节点挂掉。
共享存储实现逻辑:
- 初始化后,Active NN把editlog写 到大多数JN并返回成功(即大于等于N+1)即认定写成功。
- Standby NN定期从JN读取一批editlog, 并应用到内存中的FsImage中 。
- NameNode每次写Editlog都需要传递一个编号Epoch给JN, JN会对比Epoch,如果比自己保存的Epoch大或相同,则可以写,JN更新自己的Epoch到最新,否则拒绝操作。在切换时,Standby转换为Active时,会把Epoch+1,这样就防止即使之前的NameNode向JN写日志,即使写也会失败。
HDFS HA-防止脑裂
确保只有一个NN能命令DN。
- 每个NN改变状态的时候,向DN发送自己的状态和一个序列号。
- DN在运行过程中维护此序列号,当failover时, 新的NN在返回DN心跳时,会返回自己的active状态和一个更大的序列号。DN接收到这个返回时,认为该NN为新的active。
- 如果这时原来的active(比如GC)恢复,返回给DN的心跳信息包含active状态和原来的序列号,这时DN就会拒绝这个NN的命令。