HDFS 底层交互原理,看这篇就够了!
Posted 禅与计算机程序设计艺术
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDFS 底层交互原理,看这篇就够了!相关的知识,希望对你有一定的参考价值。
前言
HDFS全称是 Hadoop Distribute File System,是 Hadoop最重要的组件之一,也被称为分步式存储之王。
本文主要从 HDFS 高可用架构组成、HDFS 读写流程、如何保证可用性以及高频面试题出发,提高大家对 HDFS 的认识,掌握一些高频的 HDFS 面试题。
HDFS 高可用架构组成
在 HDFS 2.X 时,HDFS 提出了高可用(High Availability, HA)的方案,解决了 HDFS 1.X 时的单点问题。HA 架构模型如下图所示:
在一个 HA 集群中,会配置两个 NameNode :
一个是 Active NameNode(主),
一个是 Stadby NameNode(备)。
主节点负责执行所有修改命名空间的操作,备节点则执行同步操作,以保证与主节点命名空间的一致性。
Namenode 和 Datanode
HDFS采用master/slave架构。一个HDFS集群是由一个Namenode和一定数目的Datanodes组成。Namenode是一个中心服务器,负责管理文件系统的名字空间(namespace)以及客户端对文件的访问。集群中的Datanode一般是一个节点一个,负责管理它所在节点上的存储。HDFS暴露了文件系统的名字空间,用户能够以文件的形式在上面存储数据。从内部看,一个文件其实被分成一个或多个数据块,这些块存储在一组Datanode上。Namenode执行文件系统的名字空间操作,比如打开、关闭、重命名文件或目录。它也负责确定数据块到具体Datanode节点的映射。Datanode负责处理文件系统客户端的读写请求。在Namenode的统一调度下进行数据块的创建、删除和复制。
Namenode和Datanode被设计成可以在普通的商用机器上运行。这些机器一般运行着GNU/Linux操作系统(OS)。HDFS采用Java语言开发,因此任何支持Java的机器都可以部署Namenode或Datanode。由于采用了可移植性极强的Java语言,使得HDFS可以部署到多种类型的机器上。一个典型的部署场景是一台机器上只运行一个Namenode实例,而集群中的其它机器分别运行一个Datanode实例。这种架构并不排斥在一台机器上运行多个Datanode,只不过这样的情况比较少见。
集群中单一Namenode的结构大大简化了系统的架构。Namenode是所有HDFS元数据的仲裁者和管理者,这样,用户数据永远不会流过Namenode。
文件系统的名字空间 (namespace)
HDFS支持传统的层次型文件组织结构。用户或者应用程序可以创建目录,然后将文件保存在这些目录里。文件系统名字空间的层次结构和大多数现有的文件系统类似:用户可以创建、删除、移动或重命名文件。当前,HDFS不支持用户磁盘配额和访问权限控制,也不支持硬链接和软链接。但是HDFS架构并不妨碍实现这些特性。
Namenode负责维护文件系统的名字空间,任何对文件系统名字空间或属性的修改都将被Namenode记录下来。应用程序可以设置HDFS保存的文件的副本数目。文件副本的数目称为文件的副本系数,这个信息也是由Namenode保存的。
Block、packet及chunk 概念
在 HDFS 中,文件存储是按照数据块(Block)为单位进行存储的,在读写数据时,DFSOutputStream使用 Packet 类来封装一个数据包。每个 Packet 包含了若干个 chunk 和对应的 checksum。
Block: HDFS 上的文件都是分块存储的,即把一个文件物理划分为一个 Block 块存储。Hadoop 2.X/3.X 默认块大小为 128 M,1.X 为 64M.
Packet: 是 Client 端向 DataNode 或 DataNode 的 Pipline 之间传输数据的基本单位,默认 64 KB
Chunk: Chunk 是最小的单位,它是 Client 向 DataNode 或 DataNode PipLine 之间进行数据校验的基本单位,默认 512 Byte ,因为用作校验,所以每个 Chunk 需要带有 4 Byte 的校验位,实际上每个 Chunk 写入 Packtet 的大小为 516 Byte。
HDFS 读写流程
HDFS 读流程
HDFS 读取一个文件,调用流程如下:(中间涉及到的部分方法未列出)
usercode 调用 open() --->
DistributedFileSystem.open() --->
DFSClient.open() --->
返回一个 DFSInputStream 对象给 DistributedFileSystem --->
new hdfsDataInputStream(DFSInputStream) 并返回给用户
usercode 调用 read() --->
底层DFSIputStream.read() --->
readWithStrategy(bytArrayReader)
HDFS 写流程
HDFS 如何保证可用性?
在谈及 HDFS 如何保证可用性,要从多个方面去回答。
在 Hadoop 2.X 时,主备 NameNode 节点通过 JournalNode 的数据同步,来保证数据一致性,2个 ZKFC 进程负责各自的 NameNode 健康监控,从而实现了 NameNode 的高可用。Hadoop 3.X 时,NameNode 数量可以大于等于 2。
对于 JournalNode 来讲,也是分布式的,保证了可用性。因为有选举机制,所以 JournalNode 个数 一般都为 2N+1 个。在 主NameNode向 JournalNode写入 editlog 文件时,当有一半以上的(≥N+1) JournalNode返回写操作成功时即认为该次写成功。所以 JournalNode集群能容忍最多 N 台节点宕掉,如果多于 N 台机器挂掉,服务才不可用。
ZKFC 主要辅助 ZooKeeper 做 Namenode 的健康监控,能够保证故障自动转移,它是部署在两台 NameNode 节点上的独立的进程。此外,ZooKeeper 集群也是一个独立的分布式系统,它通过 Zab 协议来保证数据一致,和主备节点的选举切换等机制来保证可用性。
DataNode 节点主要负责存储数据,通过 3 副本策略来保证数据的完整性,所以其最大可容忍 2 台 DataNode 挂掉,同时 NameNode 会保证副本的数量。
最后,关于数据的可用性保证,HDFS 提供了数据完整性校验的机制。当客户端创建文件时,它会计算每个文件的数据块的checknums,也就是校验和,并存储在 NameNode 中。当客户端去读取文件时,会验证从 DataNode 接收的数据块的校验和,如果校验和不一致,说明该数据块已经损坏,此时客户端会选择从其它 DataNode 获取该数据块的可用副本。
HDFS 提供了两种 HA 状态切换方式:一种是管理员手动通过DFSHAAdmin -faieover执行状态切换;另一种则是自动切换。下面分别从两种情况分析故障的切换流程:
1.主 NameNdoe 宕机后,备用 NameNode 如何升级为主节点?
当主 NameNode 宕机后,对应的 ZKFC 进程检测到 NameNode 状态,便向 ZooKeeper 发生删除锁的命令,锁删除后,则触发一个事件回调备用 NameNode 上的 ZKFC
ZKFC 得到消息后先去 ZooKeeper 争夺创建锁,锁创建完成后会检测原先的主 NameNode 是否真的挂掉(有可能由于网络延迟,心跳延迟),挂掉则升级备用 NameNode 为主节点,没挂掉则将原先的主节点降级为备用节点,将自己对应的 NameNode 升级为主节点。
2.主 NameNode 上的 ZKFC 进程挂掉,主 NameNode 没挂,如何切换?
ZKFC 挂掉后,ZKFC 和 ZooKeeper 之间 TCP 链接会随之断开,session 也会随之消失,锁被删除,触发一个事件回调备用 NameNode ZKFC,ZKFC 得到消息后会先去 ZooKeeper 争夺创建锁,锁创建完成后也会检测原先的主 NameNode 是否真的挂掉,挂掉则升级 备用 NameNode 为主节点,没挂掉则将主节点降级为备用节点,将自己对应的 NameNode 升级为主节点。
HDFS高性能原理
“移动计算比移动数据更划算”
一个应用请求的计算,离它操作的数据越近就越高效,在数据达到海量级别的时候更是如此。因为这样就能降低网络阻塞的影响,提高系统数据的吞吐量。将计算移动到数据附近,比之将数据移动到应用所在显然更好。HDFS为应用提供了将它们自己移动到数据附近的接口。
HDFS 高频面试题
HDFS 客户端是如何与 DataNode 、NameNode 交互的?
ZKFC 是如何实现主 NameNode 故障自动转移的?
NameNode 存储了哪些数据?
Zookeeper 在故障转移过程中是如何起作用的?
HDFS 的读写流程?
在 Hadoop 2.X 时,HDFS block 块为什么设置为 128 M?
参考资料
https://hadoop.apache.org/docs/r1.0.4/cn/hdfs_design.html
https://www.51cto.com/article/681680.html
以上是关于HDFS 底层交互原理,看这篇就够了!的主要内容,如果未能解决你的问题,请参考以下文章