A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

本帖最后由 我是楠楠 于 2018-8-31 14:27 编辑

【郑州校区】大数据离线阶段Day3之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. 示例代码
[AppleScript] 纯文本查看 复制代码
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流形式操作
[AppleScript] 纯文本查看 复制代码
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. 代码实现
传智播客·黑马程序员郑州校区地址
河南省郑州市 高新区长椿路11号大学科技园(西区)东门8号楼三层
联系电话 0371-56061160/61/62
来校路线  地铁一号线梧桐街站A口出

您需要登录后才可以回帖 登录 | 加入黑马