分布式文件系统HDFS
计算机集群架构
集群中的计算机结点存放在机架上, 每个机架可以存放8-64个结点, 同一个机架上的不同节点通过网络互联, 多个不同机架之间采用另一级网络或交换机互联。
分布式文件系统的结构
分布式文件系统在物理结构上是由计算机集群中的多个节点构成的, 这些节点分为两类:
- 主节点或者是名称节点(NameNode):负责文件和目录的创建、删除和重命名等,同时管理着数据节点和文件块的映射关系, 客户端只有访问名称结点才能请求文件块所在的位置,进而找到相应位置读取所需文件块。
- 从结点或者是数据节点(DataNode):负责数据的存储和读取, 在存储时, 由名称结点分配存储位置, 然后由客户端把数据直接写入相应数据节点
在读取数据时, 客户端从名称节点获取数据节点和文件块的映射关系, 然后就可以到相应位置访问文件块。
数据节点也要根据名称节点的命令创建、删除数据块和冗余复制。
为了保证数据的完整性, 分布式文件系统通常采用多副本存储, 文件块会被复制为多个副本, 存储在不同的节点上, 而且存储同一个文件块的不同副本的各个节点会分布在不同机架上, 这样, 在单个节点出现故障时, 就可以快速调用副本重启单个节点上的计算过程, 而不用重启整个计算过程。
分布式文件系统是针对大规模数据存储而设计的(TB级别), 规模过小会影响性能。
HDFS特性
- 兼容廉价硬件设备
- 流数据读写
- 大数据集
- 简单的文件模型
- 强大的跨平台特性
- 不适合低延迟数据访问, 主要面向大规模数据批量处理而设计的, 采用流式数据读取, 具有很高的吞吐率, 高延迟(对于低延时要求的应用程序, HBase是一个更好的选择)
- 无法高效存储大量小文件
- 不支持多用户写入以及任意修改文件
HDFS的 相关概念
块
在传统的文件系统中,为了提高磁盘的读写效率, 一般以数据块为单位, 而不是以字节为单位。
HDFS也采用了块的概念, 默认一个块大小是64MB, 在HDFS中的文件会被拆分成多个块, 每个块作为独立的单元进行存储。
HDFS在块的大小设计明显大于普通文件系统, 为的是最小化寻址开销(磁盘寻道开销和数据块定位开销)
通常MapReduce中的Map任务一次只处理一个块中中的数据
HDFS采用抽象块概念可以带来几个好处:
- 支持大规模文件存储: 一个大规模文件可以被拆分成若干个文件块, 不同的文件块被分发到不同的节点上, 因此一个文件的大小不会受到单个节点的存储容量的限制, 可以远大于任意节点的存储容量。
- 简化系统设计:方便计算一个节点可以存储多少个文件块,其次,方便元数据的管理,元数据不需要和文件夹一起存储,可以由其他系统负责管理元数据。
- 适合数据备份:每个文件块可以冗余存储到多个节点上,大大提高了系统的容错性和可用性。
名称节点和数据节点
在名称节点(NameNode)中, 负责管理分布式文件系统的命名空间(Namespace), 保存了两个核心的数据结构, 即FsImage和EditLog。
- FsImage用于维护文件系统树以及文件树中所有的文件和文件夹的元数据
- EditLog是操作日志文件,记录了所有针对文件的创建、删除、重命名等操作。
名称节点记录了每个文件各个块所在的数据节点的位置信息, 但是不会持久化保存这些数据, 而是在系统每次启动时, 扫描所有数据节点然后重构这些信息。
名称节点启动时会处于安全模式, 对外只提供读操作。
名称节点在启动时, 会将FsImage加载到内存中, 然后执行EditLog文件中的各项操作, 使得内存中的元数据保持最新, 然后创建一个新的FsImage和空的EditLog文件, 名称节点启动成功之后进入正常运行状态, HDFS中的更新操作都会写入EditLog中, 而不是直接写入FsImage中, 因为在分布式文件系统中, FsImage都十分庞大, 如果每次的更新都往FsImage里面添加, 会带来十分大的系统开销, 而Editlog十分小, 写入操作是十分高效的。
数据节点(DataNode)是分布式文件系统HDFS的工作节点, 负责数据的存储和读取, 会根据客户端或者名称节点的调度来进行数据的存储和检索, 并向名称节点定期发送自己所存储的块列表。
第二名称节点
在名称节点运行期间, HDFS会不断发生更新操作, 会使EditLog文件逐渐变大, 当名称节点重启时, 需要逐条执行EditLog的记录, 这个过程就会变得十分缓慢。
为了解决这个问题, HDFS采用第二名称节点(Secondary NameNode), 来完成合并EditLog与FsImage的合并操作, 减少EditLog的文件大小, 缩短名称节点重启时间
HDFS体系结构
HDFS 采用主/从结构模型, 一个HDFS集群包括一个名称节点和若干个数据节点。
名称节点是中心服务器, 负责管理文件系统的命名空间以及客户端对文件的访问。
集群中的数据节点一般是一个节点运行一个数据节点进程, 负责处理文件系统客户端的读写请求, 在名称节点的统一调度之下进行数据块的创建、删除和复制等操作,每个数据节点的数据是保存在本地Linux文件系统中的, 每个数据节点会周期性地向名称节点发送“心跳”信息, 报告自己的状态, 对于没有按时发送心跳信息的数据结构会被标记为死机, 不会在给它分配任务。
用户在使用HDFS时, 仍然可以像普通文件系统那样, 使用文件名去存储和访问文件, 在系统内部, HDFS会将一个文件切分为若干个数据块, 这些数据块会被分布存储到若干个数据节点上。
访问流程:客户端访问文件, 将文件名发送给名称节点->名称节点根据文件名查找到对应的数据块->根据数据块信息找到数据节点的位置-> 把数据节点的位置发送给客户端->客户端直接访问数据节点获取数据信息
HDFS命名空间管理
HDFS通信协议
RPC
HDFS客户端
Shell and Java API
HDFS 的存储原理
数据的冗余存储
作为分布式文件系统, 为了保证系统的容错性和可用性, HDFS采用了多副本方式对数据进行冗余存储, 通过一个数据块的多个副本会被分布到不同的数据节点上。
好处:
- 加快数据传输速度: 当多个客户端需要同时访问同一个文件时, 可以让各个客户端分别从不同的数据块副本读取数据, 加快数据的传输速度
- 检查数据错误
- 保证数据的可靠性
数据的存取策略
数据存放:HDFS采用机架为基础的数据存放策略, HDFS默认的冗余复制因子是3, 每一个文件块会被同时保存到3个地方, 其中, 有两份副本放在同一个机架上的不同机器上, 第三个副本放在不同机架的机器上。
数据读取
数据复制
数据错误与恢复
名称节点出错
- 把名称节点上的元数据同步存储到其他文件系统
- 运行一个第二名称节点
数据节点出错
- 心跳检测
数据出错
由于网络传输和磁盘错误等因素造成的数据错误。
- 采用md5和sha1对数据块进行校验。