0
点赞
收藏
分享

微信扫一扫

如何使用Java API访问HDFS为目录设置配额

温馨提示:要看高清无码套图,请使用手机打开并单击图片放大查看。


Fayson的github:

​​https://github.com/fayson/cdhproject​​


提示:代码块部分可以左右滑动查看噢


1.文档编写目的



在开发应用使用Hadoop提供的hadoop-client API来访问HDFS并进行本地调试,本篇文章Fayson主要介绍如何使用Java API访问Kerberos环境下的HDFS并为目录设置配额。


  • 内容概述

1.环境准备

2.Kerberos环境为HDFS目录设置配额

3.配额测试及总结


  • 测试环境

1.CM和CDH版本为CDH5.14.3

2.OS为Redhat7.2


  • 前置条件

1.HDFS服务运行正常

2.JDK1.8


2.环境准备



1.在工程的pom.xml文件中添加Maven依赖


<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.6.0-cdh5.11.2</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.6.0-cdh5.11.2</version>
</dependency>

(可左右滑动)


2.创建一个hdfs/admin的Kerberos账号,用于以hdfs管理员身份管理HDFS


[root@cdh01 hdfs-admin-run]# kadmin.local 
kadmin.local: addprinc hdfs/admin@FAYSON.COM
kadmin.local: xst -norandkey -k hdfs.keytab hdfs/admin@FAYSON.COM

(可左右滑动)


如何使用Java API访问HDFS为目录设置配额_java


使用如下命令查看导出的hdfs.keytab文件


[root@cdh01 ~]# klist -ek hdfs.keytab 

(可左右滑动)


如何使用Java API访问HDFS为目录设置配额_java_02


3.获取集群krb5.conf文件,内容如下(非Kerberos集群可跳过此步)


[root@cdh01 ~]# vim /etc/krb5.conf
# Configuration snippets may be placed in this directory as well
includedir /etc/krb5.conf.d/
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
dns_lookup_realm = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = false
default_realm = FAYSON.COM
#default_ccache_name = KEYRING:persistent:%{uid}
[realms]
FAYSON.COM = {
kdc = cdh01.fayson.com
admin_server = cdh01.fayson.com
}
[domain_realm]
.fayson.com = FAYSON.COM
fayson.com = FAYSON.COM

(可左右滑动)


如何使用Java API访问HDFS为目录设置配额_java_03


4.通过Cloudera Manager下载HDFS客户端配置


如何使用Java API访问HDFS为目录设置配额_hdfs_04


3.编写代码通过API访问HDFS设置配额示例



1.将准备好的配置文件拷贝至工程的kb-conf目录下


如何使用Java API访问HDFS为目录设置配额_hadoop_05


2.创建conf.properties配置文件,内容如下:


kerberos.isenable=true
kerberos.debug=true
kerberos.principal=hdfs/admin@FAYSON.COM
kerberos.keytab=hdfs.keytab

(可左右滑动)


如何使用Java API访问HDFS为目录设置配额_hadoop_06


3.新建HDFSAdminUtils.java工具类,内容如下:


package com.cloudera.hdfs.utils;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.client.HdfsAdmin;
import java.io.IOException;
/**
* package: com.cloudera.hdfs.utils
* describe: HDFSAdmin API 工具类
* creat_user: Fayson
* email: htechinfo@163.com
* creat_date: 2018/6/8
* creat_time: 上午11:01
* 公众号:Hadoop实操
*/
public class HDFSAdminUtils {
/**
* 设置HDFS指定目录下文件总数
* @param hdfsAdmin
* @param path
* @param quota
*/
public static void setQuota(HdfsAdmin hdfsAdmin, Path path, long quota) {
try {
hdfsAdmin.setQuota(path, quota);
System.out.println("成功设置HDFS的" + path.getName() + "目录文件数为:" + quota);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 设置HDFS指定目录目录空间大小
* @param hdfsAdmin
* @param path
* @param quota
*/
public static void setSpaceQuota(HdfsAdmin hdfsAdmin, Path path, long quota) {
try {
hdfsAdmin.setSpaceQuota(path, quota);
System.out.println("成功设置HDFS的" + path.getName() + "目录空间大小为:" + quota);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 清除指定HDFS目录的所有配额限制
* @param hdfsAdmin
* @param path
*/
public static void clrAllQuota(HdfsAdmin hdfsAdmin, Path path) {
try {
hdfsAdmin.clearSpaceQuota(path);
hdfsAdmin.clearQuota(path);
System.out.println("成功清除HDFS的" + path.getName() + "目录的配额限制");
} catch (IOException e) {
e.printStackTrace();
}
}
}

(可左右滑动)


4.新建HDFSAdminTest.java类,内容如下:


package com.cloudera.hdfs.basic;
import com.cloudera.hdfs.utils.HDFSAdminUtils;
import com.cloudera.hdfs.utils.HDFSUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.client.HdfsAdmin;
import org.apache.hadoop.security.UserGroupInformation;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
/**
* package: com.cloudera.hdfs.basic
* describe: 使用HDFS的Client Admin API操作HDFS,Kerberos环境下访问
* creat_user: Fayson
* email: htechinfo@163.com
* creat_date: 2018/6/8
* creat_time: 上午10:24
* 公众号:Hadoop实操
*/
public class HDFSAdminTest {
private static String confPath = System.getProperty("user.dir") + File.separator + "conf";
public static void main(String[] args) {
try {
File file = new File(confPath + File.separator + "conf.properties");
if(!file.exists()) {
System.out.println("配置文件不存在");
System.exit(0);
}
Properties properties = new Properties();
properties.load(new FileInputStream(file));
//初始化HDFS Configuration 配置
Configuration configuration = HDFSUtils.initConfiguration(confPath);
if(properties.getProperty("kerberos.isenable").equals("true")) {
initKerberosENV(configuration, properties);
}
FileSystem fileSystem = FileSystem.get(configuration);
HdfsAdmin hdfsAdmin = new HdfsAdmin(fileSystem.getUri(), configuration);
//获取操作类型
String operation = args[0];
switch (operation) {
case "setQuota":
HDFSAdminUtils.setQuota(hdfsAdmin, new Path(args[1]), Long.parseLong(args[2]));
break;
case "setSpaceQuota":
HDFSAdminUtils.setSpaceQuota(hdfsAdmin, new Path(args[1]), Long.parseLong(args[2]));
break;
case "clrAllQuota":
HDFSAdminUtils.clrAllQuota(hdfsAdmin, new Path(args[1]));
break;
default:
System.out.print("操作类型错误");
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 初始化Kerberos环境
*/
public static void initKerberosENV(Configuration conf, Properties properties) {
System.setProperty("java.security.krb5.conf", confPath + File.separator + "krb5.conf");
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
System.setProperty("sun.security.krb5.debug", properties.getProperty("kerberos.debug"));
try {
UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab(properties.getProperty("kerberos.principal"), confPath + File.separator + properties.getProperty("kerberos.keytab"));
System.out.println(UserGroupInformation.getCurrentUser());
} catch (IOException e) {
e.printStackTrace();
}
}
}

(可左右滑动)


4.配额测试



将工程编译打包,上传至集群的服务器,封装为一个可执行的脚本测试。


1.使用mvn命令将工程编译,将生成的jar包拷贝至hdfs-admin-run/lib目录下


如何使用Java API访问HDFS为目录设置配额_hdfs_07


2.将工程kb-conf目录下的配置文件拷贝至conf目录下


如何使用Java API访问HDFS为目录设置配额_java_08


3.修改run.sh脚本中JAVA的环境变量


#!/bin/bash
JAVA_HOME=/usr/java/jdk1.8.0_131-cloudera
for file in `ls lib/*jar`
do
CLASSPATH=$CLASSPATH:$file
done
export CLASSPATH
${JAVA_HOME}/bin/java com.cloudera.hdfs.basic.HDFSAdminTest $@

(可左右滑动)


如何使用Java API访问HDFS为目录设置配额_hdfs_09


4.在命令行执行如下命令,为/testquota目录设置目录文件数为2


[root@cdh01 hdfs-admin-run]# sh run.sh setQuota /testquota 2

(可左右滑动)


如何使用Java API访问HDFS为目录设置配额_java_10


向/testquota目录下put两个测试文件


[root@cdh01 hdfs-admin-run]# klist
[root@cdh01 hdfs-admin-run]# hadoop fs -ls /testquota
[root@cdh01 hdfs-admin-run]# hadoop fs -put run.sh /testquota
[root@cdh01 hdfs-admin-run]# hadoop fs -put /root/jdk-8u131-linux-x64.tar.gz /testquota

(可左右滑动)


如何使用Java API访问HDFS为目录设置配额_hadoop_11


通过设置了HDFS的/testquota目录的文件数量为2,经过测试将两个文件put到/testquota目录提示目录配额为2put的文件数已超出配额,不允许上传了。


5.为/testquota目录设置文件数量的配额同时设置目录空间大小为128MB


[root@cdh01 hdfs-admin-run]# sh run.sh setSpaceQuota /testquota 134217728

(可左右滑动)


如何使用Java API访问HDFS为目录设置配额_hadoop_12


向/testquota目录下put一个大于128MB的文件,进行测试


[root@cdh01 hdfs-admin-run]# klist
[root@cdh01 hdfs-admin-run]# hadoop fs -rmr /testquota/*
[root@cdh01 hdfs-admin-run]# hadoop fs -put /root/jdk-8u131-linux-x64.tar.gz /testquota

(可左右滑动)


如何使用Java API访问HDFS为目录设置配额_java_13


通过测试可以看到put文件失败,文件大小已超出文件配额限制,可以看到我们设置的配额大小为128MB,put一个170多MB的文件,提示需要额外的384MB空间,通过该提示可以看出,目录配额大小是按照HDFS默认的3副本进行计算的。


6.清除文件配额限制


[root@cdh01 hdfs-admin-run]# sh run.sh clrAllQuota /testquota

(可左右滑动)


如何使用Java API访问HDFS为目录设置配额_java_14


测试目录配额限制已取消


[root@cdh01 hdfs-admin-run]# hadoop fs -put /root/jdk-8u131-linux-x64.tar.gz /testquota
[root@cdh01 hdfs-admin-run]# hadoop fs -put run.sh /testquota
[root@cdh01 hdfs-admin-run]# hadoop fs -ls /testquota

(可左右滑动)


如何使用Java API访问HDFS为目录设置配额_hadoop_15


通过测试清除目录配额后可以没有限制的向/testquota目录put任意大小的文件和文件数。


5.总结



1.在通过Java API访问Kerberos环境的CDH集群时,如果要使用HdfsAdmin API则需要指定用户为hdfs用户,否则会提示没有权限操作。


2.可以通过Java程序调用HdfsAdmin的API接口设置HDFS目录的配额及清除目录配额操作。


3.设置空间配额大小时,单位精确到byte,设置配额文件数时,文件数含父目录数。


4.目录空间配额大小是按照默认HDFS设置的副本数进行计算的(如:HDFS的副本数为3,则占用目录的空间配额为:文件大小 * 3)。


5.通过API的方式设置了目录空间的配额,在CM界面是不会显示出来的。


GitHub源码地址:

​​https://github.com/fayson/cdhproject/tree/master/hdfsdemo/hdfs-admin-run​​

​​https://github.com/fayson/cdhproject/blob/master/hdfsdemo/src/main/java/com/cloudera/hdfs/basic/HDFSAdminTest.java​​

​​https://github.com/fayson/cdhproject/blob/master/hdfsdemo/src/main/java/com/cloudera/hdfs/utils/HDFSAdminUtils.java​​



提示:代码块部分可以左右滑动查看噢


为天地立心,为生民立命,为往圣继绝学,为万世开太平。

温馨提示:要看高清无码套图,请使用手机打开并单击图片放大查看。



推荐关注Hadoop实操,第一时间,分享更多Hadoop干货,欢迎转发和分享。

如何使用Java API访问HDFS为目录设置配额_java_16

原创文章,欢迎转载,转载请注明:转载自微信公众号Hadoop实操


举报

相关推荐

0 条评论