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.? 代码实现
来源: http://www.bubuko.com/infodetail-3205474.html