一、分布式文件系统
分布式文件系统的设计一般采用“客户机/服务器”模式。
计算机集群结构
计算机节点放在Rack上,每个Rack可存放8-64个节点。
同一Rack上采用吉比特以太网连接,不同Rack上采用另一级网络或交换机互联。
分布式文件系统的结构
磁盘被文件系统划分为512byte一组——“磁盘块”,是文件系统进行读写操作的最小单位。
文件系统的块是磁盘块的整数倍。
HDFS默认的一个块大小为64MB
节点分为两类:
主节点(名称节点)
负责文件和目录的创建、删除和重命名等
管理数据节点和文件块的映射关系
从节点(数据节点)
负责数据的存储和读取
分布式文件系统的设计需求
- 透明性
- 并发控制
- 文件复制
- 硬件和操作系统的异构性
- 可伸缩性
- 容错
- 安全
二、HDFS的实现目标
- 兼容廉价的硬件设备
- 流数据读写
- 大数据集
- 简单的文件模型
- 强大的跨平台兼容性
- 不适合低延迟数据访问
- 无法高效存储大量小文件
- 不支持多用户写入及任意修改文件
三、HDFS的相关概念
块
默认64MB——大于普通文件系统,目的是最小化寻址开销
好处:
- 支持大规模文件存储
- 简化系统设计
- 适合数据备份
名称节点和数据节点
名称节点:负责管理分布式文件系统的命名空间,保存两个核心的数据结构FsImage、EditLog。
- FsImage:维护文件系统树及文件树中所有的文件和文件夹的元数据
- EditLog:记录了所有针对文件的创建、删除、重命名等操作。
数据节点:工作节点,负责数据的存储和读取,定期发送自己所存储的块的信息列表。
第二名称节点
- 合并FsImage和EditLog操作
- 作为名称节点的“检查点”
四、HDFS体系结构
HDFS命名空间管理
命名空间:目录、文件、块
整个集群仅一个命名空间,唯一一个名称节点
不支持硬连接和软连接
通信协议
构建在TCP/IP基础上
客户端通过一个可配置的端口向nn主动发起TCP连接,使用客户端协议交互
名称节点和数据节点之间:RPC(名称节点不会主动发起RPC,而是响应)
客户端和数据节点之间:RPC
局限性
- 命名空间的限制——受限于名称节点的内存空间大小
- 性能的瓶颈——受限于单个名称节点的吞吐量
- 隔离问题——只有一个命名空间,无法对不同应用程序隔离
- 集群的可用性——名称节点故障,整个不可用
五、HDFS的存储原理
数据的冗余存储
优点:
- 加快数据传输速度
- 容易检查数据错误
- 保证数据的可靠性
数据存取策略
- 数据存放,默认冗余复制因子是3,两个副本放在同一机架上,一个副本放在不同机架上。
- 数据读取,HDFS提供了一个API可以确定一个数据节点所属的机架ID,客户端可调用API获取自己所属的机架ID,优先选择相同机架读取
- 数据复制,流水复制策略。
数据错误与恢复
- 名称节点出错:一是把名称节点上的元数据信息同步存储到其他文件系统;二是运行一个第二名称节点,利用第二名称节点中的元数据信息进行系统恢复。
- 数据节点出错:定期检查数据块的副本数量,如果小,则启动数据冗余复制。
- 数据出错:采用MD5和SHA-1进行校验。如果出错则客户端请求到另外一个数据节点读取该文件块,并且名称节点会定期检查并复制该块。
HDFS的读写过程
读
- 客户端通过FileSystem.open()打开文件。DistributedFileSystem具体实现了FileSystem,调用open后,创建了输入流:FSData InputStream。对于HDFS,具体的输入流:DFSInputStream。
- DFSInputStream的构造函数中,通过ClientProtocal.getBlockLocation()远程调用名称节点,获取数据块信息。DistributedFileSystem利用DFSInputStream实例化FSDataInputStream返回客户端,同时返回数据节点地址(已排序)。
- 客户端获得输入流FSDataInputStream,调用read()读取,选择最近的数据节点。
- 数据从该节点读取到客户端,完成后,FSDataInputStream关闭与该节点的连接。
- FSDataInputStream通过getBlockLocations()查找下一个数据块(如果缓存中已有,则不需要调用)。
- 找到该数据块的最佳数据节点读取数据。
- 调用FSDataInputStream的close()关闭输入流。
写
- 客户端通过FileSystem.creat()创建文件,调用creat(),DistributedFileSystem创建输出流FSDataOutputStream。对于HDFS具体的输出流:DFSOutputStream。
- DistributedFileSystem通过RPC远程调用名称节点,在命名空间中创建新文件。名称节点检查后,构建新文件并添加信息。RPC后,DistributedFileSystem利用DFSOutputStream实例化FSDataOutputStream返回给客户端,客户端使用该输出流写数据。
- 客户端调用write()向HDFS中对应的文件写入数据
- 客户端向FSDataOutputStream写入的数据会被分包,放入DFSOutputStream对象的内部队列。FSDataOutputStream向名称节点申请数据节点保存文件及副本,数据节点形成数据流管道,采用流水线复制策略。
- 为保证准确性,需返回“确认包”(ACK Packet)。
- 客户端调用close()关闭输出流。客户端不会向FSDataOutputStream写入数据。当DFSOutputStream对象内部队列中的分包收到应答,即正确传输后,使用ClientProtocol.complete()通知名称节点关闭文件,完成读写。
HDFS命令
- hadoop fs 适用于任何不同的文件系统。
- hadoop dfs 仅适用于HDFS文件系统
- hdfs dfs 同上。