1、进程理解
NameNode(NN)
功能:
-
负责客户端请求的响应
-
保存文件元数据信息(文件的归属、文件的权限、 文件的大小,时间、文件与block块间映射信息 )
-
收集block块位置信息:
-
1、在系统启动时(NN不存储block与DN映射信息;在启动时,DN会向NN汇报block存储信息;NN在接收信息后重新生成映射关系:文件--block block--DN;如果数据块的副本数小于设置数,那么NN会将这个副本拷贝到其他节点 )
-
2、在集群运行中(NN与DN保持心跳机制,三秒钟发送一次;当超过三秒没有心跳后,NN则会认为该DN出现异常,此时不会让新的数据写到这个异常的DN中,客户端访问的时候不提供异常DN节点地址;如果超过十分钟没有心跳,那么NN会将当前DN节点存储的数据转移到其他的节点 )
-
NameNode所有操作在内存中进行
DataNode(DN)
功能:
-
存放的是文件的数据信息,以及验证文件完整性的校验信息
-
NameNode非常排斥存储小文件(能存,但是不推荐!)
-
汇报:
-
启动时:汇报之前会验证Block文件是否被损坏;向NN汇报当前DN上block的信息。
-
运行中:向NN保持心跳机制。
-
客户端写数据时,会先向NN获取block与DN的映射信息,然后客户端直接与DN建立连接,然后读写数据。
机架感知
副本的存放:
HDFS默认存放三个副本。
第一个副本: 存放在本地节点,即客户端所在节点;如果客户端在集群之外,选择资源丰富且不繁忙的节点作为第一个节点。
第二个副本:存放在与第一个副本不同机架的节点上。
第三个副本:存放在与第二个副本相同机架的不同节点上。
SecondaryNameNode(SNN)
2、安全模式
NameNode启动时:
-
启动 NameNode,NameNode 加载 fsimage 到内存,对内存数据执行 edits log 日志中的事务操作。
-
文件系统元数据内存镜像加载完毕,进行 fsimage 和 edits log 日志的合并,并创建新的fsimage文件和一个空的edits log日志文件。
-
NameNode 等待 DataNode 上传 block 列表信息,直到副本数满足最小副本条件。
-
当满足了最小副本条件,再过 30 秒,NameNode 就会退出安全模式。(当副本数不足时,则会从有的DN拷贝到其他DN:在拷贝的过程中系统还是处于安全模式)
安全模式:对文件系统元数据进行只读操作;当文件的所有 block 信息具备的情况下,对文件进行只读操作;不允许进行文件修改(写,删除或重命名文件)
3、HDFS读写流程
写数据
宏观过程:
1、客户端向HDFS发出写数据请求
2、NN会校验是否有足够的空间权限等条件创建这个文件,或者这个路径是否已经存在
3、校验通过,则创建一个FSDataOutputStream通道
4、客户端向NN获取第一个block存储信息
5、客户端直接与存储block的DN节点创建连接(pipeline管道)
6、客户端将block切分数据,以packet(64K)发送(详细见图),当客户端接收到block最后一个packet的成功状态,说明该block传输成功,管道撤销;客户端将这个消息传递给 NN , NN 确认传输完成;客户端会继续向 NN 询问第二个块的存储位置 , 依次类推;当所有的block传输完成后,关闭FSDataOutputStream通道。
微观过程:
packet的组成:
1、客户端首先从自己的硬盘中以流的形式将自己的数据读取到缓存中
2、然后将缓存中的数据以chunk(512B)和checksum(4B)的方式放入到packet(64k)
chunk:储存真实数据
checksum:校验数据完整性
3、(默认生成的快,发送的慢)当packet满的时候添加到dataqueue
4、datastreamer开始从DataQueue队列上读取一个packet,通过FDSDataOPS发送到pipeline
在DataQueue取出packet时,也会将该packet加入到ArkQueue中
当pipeline中返回ark为true时,ArkQueue中的该packet则会被删除;
当返回为false时,将 AckQueue 中所有的 packet 重新挂载到发送队列(DataQueue) , 重新发送
读数据:
1、首先客户端发送请求到 DFS ,申请读取某一个文件
2、DFS 去 NN 查找这个文件的信息 ( 权限 , 文件是否存在 ) 如果文件不存在,抛出指定的错误 如果文件存在,返回成功状态
3、DFS 创建 FSDataInputStream 对象,客户端通过这个对象读取数据
4、客户端获取文件第一个 Block 信息 , 返回 DN1 DN2 DN8
5、客户端直接就近原则选择 DN1 对应的数据即可
6、依次类推读取其他块的信息,直到最后一个块 , 将 Block 合并成一个文件
7、关闭 FSDataInputStream
4、NameNode的高可用
NameNode的高可用架构:
Active NameNode 和 Standby NameNode:ANN 和 NameNode 的功能和原理一样,SNN 是 ANN的备用节点,不发出任何指令。
共享日志存储:ANN 向 JournalNode 集群写入日志文件,SNN 向 JournalNode 集群读取日志文件。
主备切换控制器 ZKFailoverController (ZKFC:故障控制转移器):ZKFC主要包括两部分 HealthMonitor(HM)和 ActiveStandbyElector(ASE),HM 主要检测 NameNode 的健康情况,ASE 内部封装了 Zookeeper 的处理逻辑,完成自动的主备选举。
JournalNode理解:
当搭建好集群的时候,格式化主备节点的时候,ANN 和 SNN 都会默认创建 fsimage_000000000000000 这样的镜像文件。
ANN 产生日志文件的时候,就会同时发送到 JournalNode 的集群中每个节点上;半数以上节点接收到日志文件,那么该日志文件就生效。
SNN 从 JN 上拉取日志文件,与 fsimage 镜像文件合并。
SNN 将合并好的 fsimage 发送给 ANN,ANN 验证无误后,存放到自己的目录中 。
一次只能有一个 NameNode 节点处于活跃状态。
过程描述:
NameNode 在选举成功后, ActiveStandbyElector 会在 zk 上创建一个 ActiveStandbyElectorLock 临时节点,而没有选举成功的备 NameNode 中的ActiveStandbyElector 会监控这个节点。
如果 Active NameNode 对应的 HealthMonitor 检测到 NameNode 的状态异常时,ZKFailoverController 会主动删除当前在 Zookeeper 上建立的临时节点ActiveStandbyElectorLock。
处于 Standby 状态的 NameNode 的 ActiveStandbyElector 注册的监听器就会收到这个节点的 NodeDeleted 事件,并创建 ActiveStandbyElectorLock 临时节点,本来处于 Standby 状态的 NameNode 就选举为 Active NameNode 并随后开始切换为 Active 状态。
如果是 Active NameNode 的机器整个宕掉的话,那么跟 Zookeeper 连接的客户端线程也挂了 , 会话结束 , 那么根据 Zookeeper 的临时节点特性, ActiveStandbyElectorLock 节点会自动被删除,从而也会自动进行一次主备切换。