分布式文件系统,架构于网络之上,引入网络编程的复杂性
HDFS:Haddop Distributed Filesystem
HDFS设计
超大文件、流式数据访问:HDFS的构建思路是一次写入、多次读取是最高效的访问模式。、商用硬件
低时间延迟的数据访问:HDFS是为高数据吞吐量应用优化的,可能会以提高时间延迟为代价。、大量的小文件:由于namenode将文件系统的元数据存储在内存中,因此该文件系统所能存储的文件总数受限于namenode的内存容量。、多用户写入,任意修改文件:HDFS中的文件可能只有一个writer,而且写操作总是将数据添加在文件的末尾,不支持多个写入者,也不支持任意修改。
HDFS概念
数据块,默认为64M,块非常适合用于数据备份进而提供数据容错能力和提高可用性。将每个块复制到少数几个独立的机器上(默认是3)
- 一个文件的大小可以大于网络中任意一个磁盘的容量。文件的所有块不需要存储在同一个磁盘上,因此它们可以利用集群上的任意一个磁盘进行存储。
- 简化了存储子系统的设计,将存储子系统控制单元设置为块,可简化存储管理,同时元数据就不需要和块一同存储,用一个单独的系统就可以管理这些块的元数据。
- 数据块适合用于数据备份进而提供数据容错能力和提高可用性。
namenode和datanode,管理者-工作者模式运行
namenode管理文件系统的命名空间,维护文件系统树及整颗树内的所有文件和目录。这些信息以两个文件形式永久保存在本地磁盘上:命名空间镜像文件和编辑日志文件。namenode也记录每个文件中各个块所在的数据节点信息,但它并不永久保存块的位置信息,这些信息会在系统启动的时候由数据节点重建。
datanode是文件系统的工作节点。它们根据需要存储并检索数据块,并且定期向namenode发送它们所存储的块的列表。
联邦hdfs,允许系统通过添加namenode实现扩展
HDFS高可用性,活动namenode和备用namenode,当活动namenode失效,备用namennode就会接管它的任务并开始服务于来自客户端的请求,不会有明显的中断。架构实现包括:编辑日志的共享,datanode同时向两个namenode发送数据块处理报告,客户端使用特定的机制来处理namenode失效问题。
命令行接口,Hadoop文件系统的shell命令fs
两个属性项:
fs.default.name 用来设置Hadoop的默认文件系统,设置hdfs URL则是配置HDFS为Hadoop的默认文件系统。
dfs.replication 设置文件系统块的副本个数
文件系统的基本操作:hadoop fs -help可以获取所有的命令及其解释
常用的有:
- hadoop fs -ls / 列出hdfs文件系统根目录下的目录和文件
- hadoop fs -copyFromLocal <local path> <hdfs path> 从本地文件系统将一个文件复制到HDFS
- hadoop fs -rm -r <hdfs dir or file> 删除文件或文件夹及文件夹下的文件
- hadoop fs -mkdir <hdfs dir>在hdfs中新建文件夹
在core-site.mxl中指定主机的默认uri为hdfs://localhost
hadoop是java写的
数据流
HDFS读取文件过程:
过程描述:
(1)客户端调用FileSyste对象的open()方法在分布式文件系统中
打开要读取的文件。
(2)分布式文件系统通过使用RPC(远程过程调用)来调用namenode,
确定文件起始块的位置。
(3)分布式文件系统的DistributedFileSystem类返回一个支持文件定位的输入流FSDataInputStream对象,FSDataInputStream对象接着封装DFSInputStream对象(
存储着文件起始几个块的datanode地址),客户端对这个输入流调用read()方法。
(4)DFSInputStream连接距离最近的datanode,通过反复调用read方法,
将数据从datanode传输到客户端。
(5) 到达块的末端时,DFSInputStream关闭与该datanode的连接,
寻找下一个块的最佳datanode。
(6)客户端完成读取,对FSDataInputStream调用close()方法
关闭连接。
HDFS文件写入的过程:
过程描述:
写文件过程分析:
(1) 客户端通过对DistributedFileSystem对象调用create()函数来
新建文件。
(2) 分布式文件系统对namenod创建一个RPC调用,在文件系统的
命名空间中新建一个文件。
(3)Namenode对新建文件进行检查无误后,分布式文件系统返回给客户端一个FSDataOutputStream对象,FSDataOutputStream对象封装一个DFSoutPutstream对象,负责处理namenode和datanode之间的通信,
客户端开始写入数据。
(4)FSDataOutputStream将
数据分成一个一个的数据包,写入内部队列“数据队列”,DataStreamer负责将数据包依次流式传输到由一组namenode构成的管线中。
(5)DFSOutputStream维护着确认队列来等待datanode收到确认回执,
收到管道中所有datanode确认后,数据包从确认队列删除。
(6)
客户端完成数据的写入,对数据流调用close()方法。
(7)
namenode确认完成。
namenode如何选择在那个datanode存储复本?
需要对可靠性,写入带宽和读取带宽进行权衡。默认布局是:在运行客户端的节点上放第一个复本(如果客户端运行在集群之外,则在避免挑选存储太满或太忙的节点的情况下随机选择一个节点。)第二个复本放在与第一个不同且随机另外选择的机架中节点上。第三个复本与第二个复本放在同一个机架上,且随机选择另一个节点。其它复本放在集群中随机选择的节点中,尽量避免在同一个机架上放太多复本。
一个复本个数为3的集群放置位置如图: