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();
}
}
}