天天看点

《Hadoop海量数据处理:技术详解与项目实战》一3.3 如何访问HDFS

本节书摘来异步社区《hadoop海量数据处理:技术详解与项目实战》一书中的第3章,第3.3节,作者: 范东来 责编: 杨海玲,更多章节内容可以访问云栖社区“异步社区”公众号查看。

hadoop海量数据处理:技术详解与项目实战

hdfs提供给hdfs客户端访问的方式多种多样,用户可以根据不同的情况选择不同的方式。

hadoop自带一组命令行工具,而其中有关hdfs的命令是其工具集的一个子集。命令行工具虽然是最基础的文件操作方式,但却是最常用的。作为一名合格的hadoop开发人员和运维人员,熟练掌握是非常有必要的。

执行hadoop dfs命令可以显示基本的使用信息。

表3-2列出了hadoop命令行接口,并用例子说明各自的功能。

《Hadoop海量数据处理:技术详解与项目实战》一3.3 如何访问HDFS

本地访问hdfs最主要的方式是hdfs提供的java应用程序接口,其他的访问方式都建立在这些应用程序接口之上。为了访问hdfs,hdfs客户端必须拥有一份hdfs的配置文件,也就是hdfs-site.xml文件,以获取namenode的相关信息,每个应用程序也必须能访问hadoop程序库jar文件,也就是在$hadoop_home、$hadoop_home/lib下面的jar文件。

hadoop是由java编写的,所以通过java api可以调用所有的hdfs的交互操作接口,最常用的是filesystem类,它也是命令行hadoop fs的实现,其他接口在这一节也会有 介绍。

1.java.net.url

先来看一个例子,如代码清单3-1所示。

代码清单3-1 java.net.url示例

编译代码清单3-1所示的代码,导出为xx.jar文件,执行命令:

执行完成后,屏幕上输出hdfs的文件/user/hadoop/test的文件内容。

该程序是从hdfs读取文件的最简单的方式,即用java.net.url对象打开数据流。代码中,静态代码块的作用是让java程序识别hadoop的hdfs url。

2.org.apache.hadoop.fs.filesystem

虽然上面的方式是最简单的方式,但是在实际开发中,访问hdfs最常用的类还是filesystem类。

(1)读取文件

读取文件的示例如代码清单3-2所示。

代码清单3-2 读取文件示例

编译代码3-2,导出为xx.jar文件,上传至集群任意一节点,执行命令:

执行完成后控制台会输出文件内容。

filesystem类的实例获取是通过工厂方法:

其中configuration对象封装了hdfs客户端或者hdfs集群的配置,该方法通过给定的uri方案和权限来确定要使用的文件系统。得到filesystem实例之后,调用open()函数获得文件的输入流:

方法返回hadoop独有的fsdatainputstream对象。

(2)写入文件

写入文件的示例如代码清单3-3所示。

代码清单3-3 写入文件示例

编译代码清单3-3所示的代码,导出为xx.jar文件,上传至集群任意一节点,执行命令:

hadoop jar xx.jar com.hdfsclient.filecopyfromlocal

filesystem实例的create()方法返回fsdataoutputstream对象,与fsdatainputstream类不同的是,fsdataoutputstream不允许在文件中定位,这是因为hdfs只允许一个已打开的文件顺序写入,或在现有文件的末尾追加数据。

(3)创建hdfs的目录

创建hdfs目录的示例如代码清单3-4所示。

代码清单3-4 创建hdfs目录示例

编译代码清单3-4所示的代码,导出为xx.jar文件,上传至集群任意一节点,执行命令:

运行完成后可以用命令hadoop dfs -ls验证目录是否创建成功。

(4)删除hdfs上的文件或目录

删除hdfs上的文件或目录的示例如代码清单3-5所示。

代码清单3-5 删除hdfs上的文件或目录示例

编译代码清单3-5所示的代码,导出为xx.jar文件,上传至集群任意一节点,执行命令:

如果需要递归删除文件夹,则需将fs.delete(arg0, arg1)方法的第二个参数设为true。

(5)查看文件是否存在

查看文件的示例如代码清单3-6所示。

代码清单3-6 查看文件示例

编译代码清单3-6所示的代码,导出为xx.jar文件,上传至集群任意一台节点,执行命令:

(6)列出目录下的文件或目录名称

列出目录下的文件或目录名称的示例如代码清单3-7所示。

代码清单3-7 列出目录下的文件或目录名称示例

编译代码清单3-7所示的代码,导出为xx.jar文件,上传至集群任意一节点,执行命令:

运行后,控制台会打印出/user目录下的目录名称或文件名。

(7)文件存储的位置信息

文件存储的位置信息的示例如代码清单3-8所示。

代码清单3-8 文件存储的位置信息示例

编译代码清单3-8所示的代码,导出为xx.jar文件,上传至集群任意一节点,执行命令:

前面提到过,hdfs的存储由datanode的块完成,执行成功后,控制台会输出:

表示该文件被分为3个数据块存储,存储的位置分别为slave1、slave2、slave3。

3.sequencefile

sequecefile是hdfs api提供的一种二进制文件支持,这种二进制文件直接将对序列化到文件中,所以sequencefile是不能直接查看的,可以通过hadoop dfs -text命令查看,后面跟要查看的sequencefile的hdfs路径。

(1)写入sequencefile

写入sequencefile示例如代码清单3-9所示。

代码清单3-9 写入sequencefile示例

可以看到sequencefile.writer的构造方法需要制定键值对的类型。如果是日志文件,那么时间戳作为key,日志内容是value是非常合适的。

编译代码清单3-9所示的代码,导出为xx.jar文件,上传至集群任意一节点,执行命令:

运行完成后,执行命令:

可以看到如下内容:

(2)读取sequencefile

读取sequencefile示例如代码清单3-10所示。

代码清单3-10 读取sequencefile示例

编译代码清单3-10所示的代码,导出为xx.jar文件,上传至集群任意一节点,执行命令:

运行完成后,控制台会输出:

1.thrift

hdfs的底层的接口是通过java api提供的,所以非java程序访问hdfs比较麻烦。弥补方法是通过thriftfs功能模块中的thrift api将hdfs封装成一个apache thrift服务。这样任何与thrift绑定的语言都能与hdfs进行交互。为了使用thrift api,需要运行提供thrift服务的服务器,并以代理的方式访问hadoop。目前支持远程调用thrift api的语言有c++、perl、php、python和ruby。

2.fuse

用户空间文件系统(filesystem in universe,fuse)允许把按照用户空间实现的文件系统整合成一个unix文件系统。通过使用hadoop的fuse-dfs功能模块,任意一个hadoop文件系统(如hdfs)均可作为一个标准文件系统进行挂载。随后便可以使用普通unix命令,如ls、cat等与该文件系统交互,还可以通过任意一种编程语言调用posix库来访问文件系统。

其余可以访问hdfs的还有webdav、http、ftp接口,不过并不常用。

我们还可以通过namenode的50070端口号访问hdfs的web ui,hdfs的web ui包含了非常丰富并且实用的信息,如图3-10所示。通过hdfs的web ui了解集群的状况是一名合格hadoop开发和运维人员必备的条件。

我们可以直接在浏览器中输入master:9000(即namenode的主机名:端口号)便可进入web ui。如图3-10,点击“browse the filesystem”可以查看整个hdfs的目录树,点击“namenode logs”可以查看所有的namenode的日志,这对于排查错误十分有帮助。下面的表格展示了整个hdfs大致的信息,如总容量、使用量、剩余量等,其中点击“live nodes”选项,可以看到所有datanode节点的状况,如图3-11所示。

《Hadoop海量数据处理:技术详解与项目实战》一3.3 如何访问HDFS