hadoop学习笔记<三>----HDFS



 Hadoop Distributed File System
,简称HDFS,是一个分布式文件系统。

1.       特性:

1.1.    大数据集

运行在HDFS上的应用具有很大的数据集。可以是从GBTB级的。

1.2.    高容错性

hadoop集群环境下,每份数据都被保存在多个结点里边。一个结点的不可用不会导致该结点存储的数据不可用。

1.3.    高吞吐量

跑在Hdoop上的应用,更多的是做批处理,HDFS的设计中更多的考虑到了数据批处理,而不是用户交互处理。比之数据访问的低延迟问题,更关键的在于数据访问的高吞吐量。

1.4.    简单一致的模型

采用了"一次写入,多次读取"的模型。这一假设简化了数据一致性问题,并且使高吞吐量的数据访问成为可能。Map/Reduce应用或者网络爬虫应用都非常适合这个模型。目前还有计划在将来扩充这个模型,使之支持文件的附加写操作。

1.5.    可移植性

HDFS在设计的时候就考虑到平台的可移植性。这种特性方便了HDFS作为大规模数据应用平台的推广。 (可以这样理解:基于java,并且在HDFS是在本地FileSystem之上抽象出来的文件系统)

1.6.    移动计算比移动数据更高效

一个应用请求的计算,离它操作的数据越近就越高效,在数据达到海量级别的时候更是如此。因为这样就能降低网络阻塞的影响,提高系统数据的吞吐量。将计算移动到数据附近,比之将数据移动到应用所在显然更好。HDFS为应用提供了将它们自己移动到数据附近的接口。

一个简单的例子:程序X在计算机A上,数据在计算机A,BC上。普通的做法是在A上运行程序X,读取ABC上的数据,然后进行计算(或者是边读取边计算)。hadoop的做法是:将程序X同时也发送到BC上,ABC同时读取本地计算机上的数据进行计算。得出结果之后再进行汇总(当然这里只是通俗的举了个例子,实际上hadoop处理数据更为复杂)。这样就避免了在网络上传输大量数据导致的等待和BC计算能力的浪费。

 

2.       概念:

nameNode dataNode

HDFS采用了master/slave架构。HDFS由一个nameNode和若干个dataNode组成。

2.1 nameNode

nameNode类似于一个仓库管理员,负责记录数据存储在哪些仓库(dataNode)的哪些地方,同时也负责和客户端(Client)对文件的访问。nameNode作为一个中心服务器。因此当nameNode出现故障时是比较致命的。为了防止出现恶劣的后果,通常集群环境下还有一个Secondary NameNode 作为备份。

2.2 dataNode

dataNode负责文件的存储(可以理解为仓库)。

一个文件被分为多个文件块存储在一组dataNode里边。Namenode执行文件系统的名字空间操作,比如打开、关闭、重命名文件或目录。它也负责确定数据块到具体Datanode节点的映射。Datanode负责处理文件系统客户端的读写请求。在Namenode的统一调度下进行数据块的创建、删除和复制。

3.       文件流

3.1 读文件

客户端(client)FileSystemopen()函数打开文件,DistributedFileSystemRPC调用元数据节点,得到文件的数据块信息。对于每一个数据块,元数据节点返回保存数据块的数据节点的地址。DistributedFileSystem返回FSDataInputStream给客户端,用来读取数据。客户端调用streamread()函数开始读取数据。DFSInputStream连接保存此文件第一个数据块的最近的数据节点。Data从数据节点读到客户端(client),当此数据块读取完毕时,DFSInputStream关闭和此数据节点的连接,然后连接此文件下一个数据块的最近的数据节点。当客户端读取完毕数据的时候,调用FSDataInputStreamclose函数。

整个过程就是如图所示


3.2 写文件

客户端调用create()来创建文件,DistributedFileSystemRPC调用元数据节点,在文件系统的命名空间中创建一个新的文件。元数据节点首先确定文件原来不存在,并且客户端有创建文件的权限,然后创建新文件。DistributedFileSystem返回DFSOutputStream,客户端用于写数据。客户端开始写入数据,DFSOutputStream将数据分成块,写入data queueData queueData Streamer读取,并通知元数据节点分配数据节点,用来存储数据块(每块默认复制3)。分配的数据节点放在一个pipeline里。Data Streamer将数据块写入pipeline中的第一个数据节点。第一个数据节点将数据块发送给第二个数据节点。第二个数据节点将数据发送给第三个数据节点。DFSOutputStream为发出去的数据块保存了ack queue,等待pipeline中的数据节点告知数据已经写入成功。如果数据节点在写入的过程中失败:关闭pipeline,将ack queue中的数据块放入data queue的开始。

 

 

整个过程如图所示:



 
 

4.       使用命令行操作HDFS

 

1.添加目录  hadoop  fs  -mkdir /abc

  就在HDFS下创建了一个abc的目录

2.列出HDFS根目录下的文件  hadoop fs -ls  /

  列出根目录下的所有文件 hadoop fs -ls

3.复制文件   hadoop  fs  -put  /tianlong/test   /abc

4.查看文件   hadoop  fs  -cat  /abc/test

5.HDFS上取文件 hadoop  fs  -get  /abc/test  ~/test.txt  HDFS里的test文件 取回 当前用户目录的test.txt

 

5.       编程操作HDFS

下边简单介绍几个常用的API,具体的例子网上有很多,就不重复贴了。

FileSystem Hadoop文件系统通过Hadoop Path 对象来代表文件,是一个通用的文件系统API

 

 Hadoop中关于文件操作类基本上全部是在"org.apache.hadoop.fs"包中,这些API能够支持的操作包含:打开文件,读写文件,删除文件等。

 

Hadoop类库中最终面向用户提供的接口类是FileSystem,该类是个抽象类,只能通过来类的get方法得到具体类。get方法存在几个重载版本,常用的是这个:

static FileSystem get(Configuration conf) throws IOException;

static FileSystem get(URI uri, Configuration conf) throws IOException;

或者从Path对象中获得FileSystem实例

        Path dst = new Path("hdfs://192.168.0.111:9000/home");

         // 得到dstFileSystem.

         FileSystem hdfs = dst.getFileSystem(conf);

 

 

  该类封装了几乎所有的文件操作,例如mkdirdelete等。综上基本上可以得出操作文件的程序库框架:

 

operator()

{

    得到Configuration对象

    得到FileSystem对象

    进行文件操作

}

猜你喜欢

转载自ztianlong.iteye.com/blog/1745490