java通过kerberos权限认证集成hdfs

java通过kerberos权限认证集成hdfs,并操作hdfs实现增删查、赋权、目录配额等功能

1、pom文件中引入hdfs包

		<dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.7.3</version>
        </dependency>

2、从集群中下载认证过可以登录的keytab文件,以及krb5.conf文件还有core-site.xml、hdfs-site.xml、hive-site.xml、yarn-site.xml放到项目的resources目录下
(xml文件按照自己项目需要下载)
在这里插入图片描述

3、代码实现

package com.example.demo.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.hdfs.client.HdfsAdmin;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.security.UserGroupInformation;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.PrivilegedExceptionAction;


/**
 * 主要用于操作hdfs
 */
public class HDFSUtil {
    //文件系统
    private static FileSystem fileSystem;
    public static UserGroupInformation ugi = null;
    public static Configuration conf = new Configuration();

    public static void main(String[] args) throws IOException {
        connectionHDFS();//连接hdfs
        //createDir("/user/hdfs/test_username");//创建hdfs目录路径
        //delete("/user/hdfs/test_username");//删除hdfs目录路径
        //setFilePermission();//设置HDFS文件的权限
        //uploadFile("D:\\testTxt.txt","/user/hdfs/test_username/");//本地文件上传到服务器hdfs路径下
        //downloadFile("/user/hdfs/test.sql","D:\\");//服务器hdfs路径文件下载文件到本地
        //setSpaceQuota(new Path("/user/hdfs/test_username"),104857600);//设置HDFS指定目录目录空间大小 100M
        //clrAllQuota(new Path("/user/hdfs/test_username"));//清除指定HDFS目录的所有配额限制
        getHDFSData("/user/hdfs/");//查询hdfs下面的文件

    }

    public static void connectionHDFS(){
        String principal = "hdfs";  //Kerberos Principal,如果不然REALM,则使用krb5.conf默认的
        String keytabFile = "src/main/resources/hdfs.keytab";   //KDC生成的keytab文件

        conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");
        conf.set("fs.defaultFS", "hdfs://192.168.0.110:8020");  //HDFS地址
        //需要设置krb5.conf文件
        System.setProperty("java.security.krb5.conf", "src/main/resources/krb5.conf");

        try {

            UserGroupInformation.loginUserFromKeytab(principal, keytabFile);
            ugi = UserGroupInformation.getLoginUser();

            //使用UserGroupInformation来获FileSystem
            try {
                fileSystem = ugi.doAs(new PrivilegedExceptionAction<FileSystem>() {
                    @Override
                    public FileSystem run() throws Exception {
                        return FileSystem.get(conf);
                    }
                });
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /***
     * 查询hdfs下面的文件
     * @param path
     * @throws IOException
     */
    public static void getHDFSData(String path) throws IOException {
        FileStatus[] fileStatus =  fileSystem.listStatus(new Path(path));
        for (FileStatus fst : fileStatus) {
            System.out.println(fst.getPath());
        }
        // 得到一个迭代器:装有指定目录下所有的文件信息
        /*RemoteIterator<LocatedFileStatus> remoteIterator = fileSystem.listFiles(new Path(path), true);
        // 遍历迭代器
        while (remoteIterator.hasNext()) {
            LocatedFileStatus locatedFileStatus = remoteIterator.next();
            // 文件名称
            String fileName = locatedFileStatus.getPath().getName();
            // 长度
            long len = locatedFileStatus.getLen();
            // 权限
            FsPermission permission = locatedFileStatus.getPermission();
            // 所属组
            String group = locatedFileStatus.getGroup();
            // 所属用户
            String owner = locatedFileStatus.getOwner();
            System.out.println(fileName + "\t" + len + "\t" + permission + "\t" + group + "\t" + owner);
            System.out.println("================================");

            // 块信息
            BlockLocation[] blockLocations = locatedFileStatus.getBlockLocations();
            for (BlockLocation blockLocation : blockLocations) {
                String[] hosts = blockLocation.getHosts();
                for (String host : hosts) {
                    System.out.println("主机名称:" + host);
                }
            }
        }*/

    }

    /**
     * 创建一个文件夹方法
     * @param path
     */
    public static void createDir(String path) throws IOException {
        boolean flag = false;
        if (!fileSystem.exists(new Path(path))){//如果文件夹不存在
            flag = fileSystem.mkdirs(new Path(path));
        }
        if(flag){
            System.out.println("文件夹已经创建成功。。。");
        }else{
            System.out.println("文件夹已经存在。。。。");
        }
    }

    /**
     * 删除文件夹以及文件
     * @param path
     */
    public static void delete(String path) throws IOException {
        boolean flag = false;
        if(fileSystem.exists(new Path(path))){
            flag = fileSystem.delete(new Path(path),true);
        }
        if(flag){
            System.out.println("文件或者文件夹已经删除");
        }else{
            System.out.println("文件或者文件夹不存在");
        }
    }

    /**
     * 上传到hdfs上
     * @param srcPath
     * @param destPath
     * @throws IOException
     */
    public static void uploadFile(String srcPath,String destPath) throws IOException {
        fileSystem.copyFromLocalFile(false,true,new Path(srcPath),new Path(destPath));
        System.out.println("文件上传成功!!!");
    }
    public static void downloadFile(String srcPath,String destPath) throws IOException {
        // boolean delSrc 指是否将原文件删除
        // Path src 指要下载的文件路径
        // Path dst 指将文件下载到的路径
        // boolean useRawLocalFileSystem 是否开启文件校验
        fileSystem.copyToLocalFile(false,new Path(srcPath),new Path(destPath),true);
        System.out.println("文件下载成功");
    }

    /**
     * 通过流的方式上传文件到hdfs
     * @param localPath 本地路径
     * @param hdfsPath HDFS路径
     * @param isOverWrite 是否覆盖
     */
    public static void uploadStream(String localPath, String hdfsPath, boolean isOverWrite) throws Exception {
        FSDataOutputStream outputStream = fileSystem.create(new Path(hdfsPath), isOverWrite);
        FileInputStream inputStream = new FileInputStream(localPath);
        IOUtils.copyBytes(inputStream, outputStream, 4096);
    }

    /**
     * 下载HDFS文件
     * @param hdfsPath HDFS路径
     * @param localPath 本地路径
     */
    public static void downLoadStream(String hdfsPath, String localPath) throws IllegalArgumentException, IOException {
        //先获取一个文件的输入流----针对hdfs上的
        FSDataInputStream in = fileSystem.open(new Path(hdfsPath));
        //再构造一个文件的输出流----针对本地的
        FileOutputStream out = new FileOutputStream(new File(localPath));
        //再将输入流中数据传输到输出流
        IOUtils.copyBytes(in, out, 4096);
    }

    /**
     * 设置HDFS文件的权限
     */
    public static void setFilePermission(){
        try {
            fileSystem.setPermission(new Path("/user/hdfs/test_username"), new FsPermission("700"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置HDFS指定目录目录空间大小
     * hdfs dfsadmin -setSpaceQuota 104857600  hdfs://192.168.0.110/user/hdfs/test_username
     * @param path
     * @param quota
     */
    public static void setSpaceQuota(Path path, long quota) {
        HdfsAdmin hdfsAdmin = null;
        try {
            hdfsAdmin = new HdfsAdmin(fileSystem.getUri(), conf);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            hdfsAdmin.setSpaceQuota(path, quota);
            System.out.println("成功设置HDFS的" + path.getName() + "目录空间大小为:" + quota);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
      /**
     * 清除指定HDFS目录的所有配额限制
     * @param path
     */
    public static void clrAllQuota(Path path) {
        HdfsAdmin hdfsAdmin = null;
        try {
            hdfsAdmin = new HdfsAdmin(fileSystem.getUri(), conf);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            hdfsAdmin.clearSpaceQuota(path);
            hdfsAdmin.clearQuota(path);
            System.out.println("成功清除HDFS的" + path.getName() + "目录的配额限制");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要通过Kerberos认证方式上传文件到HDFS,需要完成以下步骤: 1. 配置Kerberos客户端 在Java中使用Kerberos认证需要配置Kerberos客户端。可以通过设置以下系统属性完成配置: ``` System.setProperty("java.security.krb5.realm", "EXAMPLE.COM"); System.setProperty("java.security.krb5.kdc", "kdc.example.com"); ``` 其中,`EXAMPLE.COM`为Kerberos域名,`kdc.example.com`为Kerberos服务器地址。 同时,还需要将Kerberos的keytab文件添加到JVM的classpath中,以便在运行时自动加载。 2. 获取Kerberos票据 在进行HDFS操作之前,需要获取Kerberos票据。可以使用`LoginContext`类获取Kerberos票据: ``` LoginContext lc = new LoginContext("KerberosLogin", new Subject(), null, new KerberosConfiguration()); lc.login(); Subject subject = lc.getSubject(); ``` 其中,`KerberosLogin`为登录模块名称,`KerberosConfiguration`为Kerberos配置类。 3. 创建HDFS文件系统对象 通过Hadoop的`FileSystem`类创建HDFS文件系统对象,并设置认证方式为Kerberos: ``` Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://namenode.example.com:8020"); conf.setBoolean("dfs.support.append", true); conf.set("hadoop.security.authentication", "kerberos"); conf.set("hadoop.security.authorization", "true"); UserGroupInformation.setConfiguration(conf); UserGroupInformation ugi = UserGroupInformation.getSubject(subject); FileSystem fs = ugi.doAs(new PrivilegedExceptionAction<FileSystem>() { public FileSystem run() throws Exception { return FileSystem.get(conf); } }); ``` 其中,`namenode.example.com`为HDFS的NameNode地址。 4. 上传文件到HDFS 使用HDFS文件系统对象上传文件到HDFS即可: ``` Path srcPath = new Path("/path/to/local/file"); Path dstPath = new Path("/path/to/remote/file"); fs.copyFromLocalFile(srcPath, dstPath); ``` 其中,`/path/to/local/file`为本地文件路径,`/path/to/remote/file`为HDFS文件路径。 以上就是通过Kerberos认证方式上传文件到HDFS的步骤。需要注意的是,Kerberos认证方式需要对安全性有一定的了解才能正确配置和使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值