HDFS的应用开发

1. HDFS的JAVA API操作

HDFS在生产应用中主要是客户端的开发,其核心步骤是从HDFS提供的api中构造一个HDFS的访问客户端对象,然后通过该客户端对象操作(增删改查)HDFS上的文件。

1.1. 搭建开发环境

创建Maven工程,引入pom依赖


<dependencies>

                <dependency>

                        <groupId>org.apache.hadoop</groupId>

                        <artifactId>hadoop-common</artifactId>

                        <version>2.7.4</version>

                </dependency>

                <dependency>

                        <groupId>org.apache.hadoop</groupId>

                        <artifactId>hadoop-hdfs</artifactId>

                        <version>2.7.4</version>

                </dependency>

                <dependency>

                        <groupId>org.apache.hadoop</groupId>

                        <artifactId>hadoop-client</artifactId>

                        <version>2.7.4</version>

                </dependency>

        </dependencies>

        

配置windows平台Hadoop环境

在windows上做HDFS客户端应用开发,需要设置Hadoop环境,而且要求是windows平台编译的Hadoop,不然会报以下的错误:

Failed to locate the winutils binary in the hadoop binary path java.io.IOException: Could not locate executable null\bin\winutils.exe in the Hadoop binaries.

        

为此我们需要进行如下的操作:

A、在windows平台下编译Hadoop源码(可以参考资料编译,但不推荐)

B、使用已经编译好的Windows版本Hadoop:

hadoop-2.7.4-with-windows.tar.gz

C、解压一份到windows的任意一个目录下

D、在windows系统中配置HADOOP_HOME指向你解压的安装包目录

E、在windows系统的path变量中加入HADOOP_HOME的bin目录

1.2. 构造客户端对象

在java中操作HDFS,主要涉及以下Class:

Configuration:该类的对象封转了客户端或者服务器的配置;

FileSystem:该类的对象是一个文件系统对象,可以用该对象的一些方法来对文件进行操作,通过FileSystem的静态方法get获得该对象。

FileSystem fs = FileSystem.get(conf)

get方法从conf中的一个参数 fs.defaultFS的配置值判断具体是什么类型的文件系统。如果我们的代码中没有指定fs.defaultFS,并且工程classpath下也没有给定相应的配置,conf中的默认值就来自于hadoop的jar包中的core-default.xml,默认值为: [url=]file:///[/url],则获取的将不是一个DistributedFileSystem的实例,而是一个本地文件系统的客户端对象。

 

1.3. 示例代码

Configuration conf = new Configuration();

 

//这里指定使用的是hdfs文件系统

 

conf.set("fs.defaultFS", "hdfs://node-21:9000");

 

               

 

//通过如下的方式进行客户端身份的设置

 

System.setProperty("HADOOP_USER_NAME", "root");

 

  

 

//通过FileSystem的静态方法获取文件系统客户端对象

 

FileSystem fs = FileSystem.get(conf);

 

//也可以通过如下的方式去指定文件系统的类型 并且同时设置用户身份

 

//FileSystem fs = FileSystem.get(new URI("hdfs://node-21:9000"), conf, "root");

 

  

 

//创建一个目录

 

fs.create(new Path("/hdfsbyjava-ha"), false);

 

  

 

//上传一个文件

 

fs.copyFromLocalFile(new Path("e:/hello.sh"), new Path("/hdfsbyjava-ha"));

 

   

 

//关闭我们的文件系统

 

 fs.close();

其他更多操作如文件增删改查请查看实例代码。

Stream流形式操作

public void testUpload() throws Exception { 

 

        FSDataOutputStream outputStream = fs.create(new Path("/1.txt"), true); 

 

        FileInputStream inputStream = new FileInputStream("D:\\1.txt"); 

 

        IOUtils.copy(inputStream, outputStream); 

 

  

 

    }

2. 案例:shell定时采集数据至HDFS

上线的网站每天都会产生日志数据。假如有这样的需求:要求在凌晨24点开始操作前一天产生的日志文件,准实时上传至HDFS集群上。

该如何实现?实现后能否实现周期性上传需求?如何定时?

2.1. 技术分析

HDFS SHELL:  

hadoop fs –put  //满足上传文件,不能满足定时、周期性传入。

Linux crontab:

crontab -e

0 0 * /shell/ uploadFile2Hdfs.sh   //每天凌晨12:00执行一次

2.2. 实现流程

一般日志文件生成的逻辑由业务系统决定,比如每小时滚动一次,或者一定大小滚动一次,避免单个日志文件过大不方便操作。

比如滚动后的文件命名为access.log.x,其中x为数字。正在进行写的日志文件叫做access.log。这样的话,如果日志文件后缀是1\2\3等数字,则该文件满足需求可以上传,就把该文件移动到准备上传的工作区间目录。工作区间有文件之后,可以使用hadoop put命令将文件上传。

2.3. 代码实现
HDFS的应用开发

上一篇:c++读写配置文件


下一篇:HDFS的Java API