这是我参与「第四届青训营 」笔记创作活动的第5天,学习了HDFS的相关知识,了解了NameNode和DataNode的作用,学习了HDFS的读写流程。
HDFS功能特性:需要注意HDFS尽管是一个文件系统,但是它没有完整实现POSIX文件系统规范。
HDFS的文件写入原理,主要包括以下几个步骤:
(1)客户端通过调用 DistributedFileSystem 的create方法,创建一个新的文件。
(2)DistributedFileSystem 通过 RPC(远程过程调用)调用 NameNode,去创建一个没有blocks关联的新文件。创建前,NameNode 会做各种校验,比如文件是否存在,客户端有无权限去创建等。如果校验通过,NameNode 就会记录下新文件,否则就会抛出IO异常。
(3)前两步结束后会返回 FSDataOutputStream 的对象,和读文件的时候相似,FSDataOutputStream 被封装成 DFSOutputStream,DFSOutputStream 可以协调 NameNode和 DataNode。客户端开始写数据到DFSOutputStream,DFSOutputStream会把数据切成一个个小packet,然后排成队列 data queue。
(4)DataStreamer 会去处理接受 data queue,它先问询 NameNode 这个新的 block 最适合存储的在哪几个DataNode里,比如重复数是3,那么就找到3个最适合的 DataNode,把它们排成一个 pipeline。DataStreamer 把 packet 按队列输出到管道的第一个 DataNode 中,第一个 DataNode又把 packet 输出到第二个 DataNode 中,以此类推。
(5)DFSOutputStream 还有一个队列叫 ack queue,也是由 packet 组成,等待DataNode的收到响应,当pipeline中的所有DataNode都表示已经收到的时候,这时akc queue才会把对应的packet包移除掉。
(6)客户端完成写数据后,调用close方法关闭写入流。
(7)DataStreamer 把剩余的包都刷到 pipeline 里,然后等待 ack 信息,收到最后一个 ack 后,通知 DataNode 把文件标示为已完成。
HDFS的文件读取原理,主要包括以下几个步骤:
(1)首先调用FileSystem对象的open方法,其实获取的是一个DistributedFileSystem的实例。
(2) DistributedFileSystem通过RPC(远程过程调用)获得文件的第一批block的locations,同一 block按照重复数会返回多个locations,这些locations按照hadoop拓扑结构排序,距离客户端近的排在前面。
(3) 前两步会返回一个FSDataInputStream对象,该对象会被封装成 DFSInputStream对象,DFSInputStream可以方便的管理datanode和namenode数据流。客户端调用read方法,DFSInputStream就会找出离客户端最近的datanode并连接datanode。
(4) 数据从datanode源源不断的流向客户端。
(5)如果第一个block块的数据读完了,就会关闭指向第一个block块的datanode连接,接着读取下一个block块。这些操作对客户端来说是透明的,从客户端的角度来看只是读一个持续不断的流。
(6)如果第一批block都读完了,DFSInputStream就会去namenode拿下一批blocks的location,然后继续读,如果所有的block块都读完,这时就会关闭掉所有的流。
NameNode:
(1)管理HDFS的名称空间;
(2)配置副本策略;
(3)管理数据块(Block)映射信息;
(4)处理客户端读写请求。
Datanodes是工作节点。它们是可以轻松添加到集群的廉价商品硬件。当 Namenode 要求时, Datanodes负责存储、检索、复制、删除等块。他们定期向 Namenode 发送心跳,以便它知道他们的健康状况。这样,DataNode 还会发送存储在其上的块列表,以便 Namenode 可以在其内存中维护块到 Datanodes 的映射。
HDFS 运行在 master-worker 架构中,这意味着集群中有一个 master 节点和多个 worker 节点。主节点是Namenode。Namenode是在集群中的单独节点上运行的主节点。管理文件系统命名空间,它是文件系统树或文件和目录的层次结构。存储所有文件的文件所有者、文件权限等信息。它还知道文件中所有块的位置及其大小。所有这些信息都以两个文件的形式在本地磁盘上永久维护:Fsimage和Edit Log。
Fsimage存储有关文件系统中文件和目录的信息。对于文件,它存储复制级别、修改和访问时间、访问权限、文件组成的块及其大小。对于目录,它存储修改时间和权限。另一方面,编辑日志Edit Log跟踪客户端执行的所有写操作。这会定期更新到内存中的元数据以服务读取请求。每当客户端想要向 HDFS 写入信息或从 HDFS 读取信息时,它都会与Namenode连接。Namenode 将块的位置返回给客户端并执行操作。
副本存储是可靠性和读/写带宽之间的权衡。为了提高可靠性,我们需要将块副本存储在不同的机架和 Datanode 上以提高容错能力。当副本存储在同一节点上时,写入带宽最低。因此,Hadoop 有一个默认的策略来处理这个难题,也称为Rack Awareness算法。
例如,如果一个块的复制因子是 3,那么第一个副本存储在客户端写入的同一个 Datanode 上。第二个副本存储在不同的 Datanode 上,但在不同的机架上,随机选择。第三个副本与第二个副本存储在同一机架上,但在不同的 Datanode 上,再次随机选择。但是,如果复制因子较高,则后续副本将存储在集群中的随机数据节点上。
控制面建设:保障系统稳定运行
HouseKeeping组件:比如Balancer,Mover等, 这些组件不运行不会马上影响读写操作,但是长时间会积累系统性问题,例如读写不均衡导致IO热点等。
可观测性设施:比如系统指标监控设施等,帮助快速发现定位问题。
运维体系建设:从最基本的命令行手工操作,脚本自动化再到完善的运维平台。
参考文献