HDFS简介
HDFS的目标:
· 兼容廉价的硬件设备(快速检测硬件故障、自动恢复机制)
· 流数据读写(为满足批量数据处理而设计,为提高数据吞吐率,以流式方式访问数据)
· 大数据集(GB、TB级别)
· 简单的文件模型(一次写入、多次读取;文件一旦完成写入,关闭后无法再次写入)
· 强大的跨平台兼容性(HDFS采用Java编写,跨平台性较好)
HDFS的局限性:
· 不适合低延迟数据访问(有低延迟要求时,HBase是一个更好的选择)
· 无法高效存储大量小文件(例如小于一个块(Block)的文件)
· 不支持多用户写入及任意修改文件(任何时间都只允许一个程序写入某文件;只允许对文件追加,不允许随机写)
块
块的定义(如前所述)
块的设置的意义:最小化寻址开销(数据块的定位开销、磁盘寻道开销)
当客户端访问一个文件时,
首先,从名称节点获得组成该文件的数据块的(位置)列表=>
其次,获取数据块所在的数据节点的位置=>
最后,由数据节点在本地系统中找到对应的文件,把数据返回给客户端
块的设置不宜过大,原因:
MapReduce中的Map任务一次只处理一个块中的数据,块设置过大会导致启动的Map任务太少,降低作业的并行处理速度。
名称节点和数据节点
名称节点(NameNode)的功能:
(1)负责管理分布式文件系统的命名空间(Namespace)
(2)保存两个核心的数据结构,即FsImage(命名空间镜像文件) EditLog(修改日志)
(3)名称节点记录了每个文件块所在的数据节点的位置信息,但是不持久化存储(因为信息放在内存),而是系统启动时通过扫描所有数据节点重构这些信息。
数据节点(NameNode)的功能:
(1)数据节点是分布式文件系统HDFS的工作节点,负责数据的存储和读取
(2)会根据客户端或者是名称节点的调度来进行数据的存储和检索
(3)向名称节点定期发送自己所存储的块的列表
(4)每个数据节点中的数据会被保存在各自节点的本地Linux文件系统中
第二名称节点
EditLog不断变大的问题
在名称节点运行期间,HDFS的所有更新操作都是直接写到EditLog中,因此EditLog文件会逐渐变大
当名称节点重启的时候,需要将FsImage加载到内存中,逐条执行EditLog中的记录,使得FsImage保持最新。
如果EditLog很大,名称节点在启动或失败恢复时就会变得非常慢,而在这段时间内HDFS系统处于安全模式,一直无法对外提供写操作,影响了用户的使用
如何解决EditLog不断变大的问题?
采用SecondaryNameNode第二名称节点,该节点一般是单独运行在一台机器上
功能:
(1)完成EditLog与FsImage的合并操作,减小EditLog文件大小,缩短名称节点重启时间;
(2)作为名称节点的“检查点”,保存名称节点中的元数据信息。
合并操作:
1)SecondaryNameNode定期与NameNode通信,请求其停止使用EditLog文件,暂时将新的写操作写到一个新的文件edits.new中;
2)SecondaryNameNode通过HTTP GET方式把NameNode中的FsImage和EditLog文件下载到本地,加载到内存;
3)然后一条条执行EditLog文件中的各项更新操作,使得FsImage保持最新(此为合并过程);
4)SecondaryNameNode通过post方式将合并后的FsImage文件发送到NameNode节点上;
5)NameNode将接收到的最新的FsImage替换旧的FsImage,同时用edits.new替换EditLog文件,从而减小了EditLog文件的大小
作为名称节点的“检查点”
第二名称节点相当于为名称节点设置了一个“检查点”,周期性地备份名称节点中的元数据信息;
但是第二名称节点上合并操作得到的FsImage文件并不包含edits.new的操作,因此可能丢失部分元数据信息,不能作为最新的备份,无法起到“热备份”的作用。
HDFS体系结构概述
HDFS采用主从(Master/Slave)结构模型
一个HDFS集群包含一个名称节点和若干个数据节点
客户端借助名称节点,实现对数据节点的直接读取和写入
HDFS数据读写过程
FileSystem是一个通用文件系统的抽象基类,可以被分布式文件系统继承,所有可能使用Hadoop文件系统的代码,都要使用这个类;
FileSystem的open()方法返回的是一个输入(字节)流FSDataInputStream对象;
FileSystem中的create()方法返回的是一个输出(字节)流FSDataOutputStream对象;
常用命令
hadoop fs -ls <path>:显示<path>指定的文件的详细信息
hadoop fs -mkdir <path>:创建<path>指定的文件夹
hadoop fs -cat <path>:将<path>指定的文件的内容输出到标准输出(stdout)
hadoop fs -copyFromLocal <localsrc> <dst>:将本地源文件<localsrc>复制到路径<dst>指定的文件或文件夹中
从本地向集群复制文件:
./bin/hadoop fs -put <localPath> <hdfsPath>
./bin/hadoop fs -copyFromLocal <localPath> <hdfsPath>
./bin/hadoop fs -cp <localPath> <hdfsPath>
./bin/hadoop fs -moveFromLocal <localPath> <hdfsPath>(源文件会被删除)
从集群向本地复制文件:
./bin/hadoop fs -get <hdfsPath> <localPath>