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

2018-07-12 15:22:55 浏览数 (1)

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

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依赖

代码语言:javascript复制
<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

代码语言:javascript复制
[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

(可左右滑动)

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

代码语言:javascript复制
[root@cdh01 ~]# klist -ek hdfs.keytab 

(可左右滑动)

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

代码语言:javascript复制
[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

(可左右滑动)

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

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


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

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

代码语言:javascript复制
kerberos.isenable=true
kerberos.debug=true
kerberos.principal=hdfs/admin@FAYSON.COM
kerberos.keytab=hdfs.keytab

(可左右滑动)

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

代码语言:javascript复制
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类,内容如下:

代码语言:javascript复制
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目录下

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

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

代码语言:javascript复制
#!/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 $@

(可左右滑动)

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

代码语言:javascript复制
[root@cdh01 hdfs-admin-run]# sh run.sh setQuota /testquota 2

(可左右滑动)

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

代码语言:javascript复制
[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

(可左右滑动)

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

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

代码语言:javascript复制
[root@cdh01 hdfs-admin-run]# sh run.sh setSpaceQuota /testquota 134217728

(可左右滑动)

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

代码语言:javascript复制
[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

(可左右滑动)

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

6.清除文件配额限制

代码语言:javascript复制
[root@cdh01 hdfs-admin-run]# sh run.sh clrAllQuota /testquota

(可左右滑动)

测试目录配额限制已取消

代码语言:javascript复制
[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

(可左右滑动)

通过测试清除目录配额后可以没有限制的向/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干货,欢迎转发和分享。

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

0 人点赞