前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何使用Java API访问HDFS为目录设置配额

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

作者头像
Fayson
发布2018-07-12 15:22:55
3.5K0
发布2018-07-12 15:22:55
举报
文章被收录于专栏:Hadoop实操Hadoop实操

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

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实操

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Hadoop实操 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
大数据
全栈大数据产品,面向海量数据场景,帮助您 “智理无数,心中有数”!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档