官网参考链接
Extended Attributes in HDFS(简称xattrs)
本次编写目的是如何获取集群所有目录的扩展属性信息,所以概念相关的请参考官网,这里不做过多赘述。
HDFS的扩展属性信息简要解释
这个概念其实就是额外的属性信息,通俗的理解就是HDFS目录或者文件在生成的时候会带有基础权限、用户、用户组等一些基本信息,那么我还想添加一些我认为需要备注的信息如:user.张三 values为"这个目录是张三创建的",那么通过一般的方式是做不到的,那么此时就需要HDFS的扩展属性信息技术。
截图可能更为直观一些吧
详细解释请参考官网链接。
命令示例
#获取目录的所有扩展属性
hadoop fs -getfattr -d /test/xattr/abc
#获取指定user空间的扩展属性信息(除了user还有trusted/security/system/raw)
hadoop fs -getfattr -n user /test/xattr/abc
#对目录设置扩展属性信息
hadoop fs -setfattr -n user.作者张三 -v 这个目录是张三创建的哦 /test/xattr/
接下来的步骤就是要实现如何获取集群的目录扩展属性信息了。
1、获取HDFS元数据信息
1、提取HDFS元数据信息
hdfs dfsadmin -fetchImage /tmp/fsimage/fsimage
2、以逗号分隔转换成可查看文件
hdfs oiv -i /tmp/fsimage/fsimage* -o /tmp/fsimage/hdfsfsimage.txt -p Delimited -delimiter ,
3、过滤出HDFS目录
cat /tmp/fsimage/hdfsfsimage.txt|awk -F "," '$10 ~ "^d" {print $1}' > /tmp/fsimage/hdfsdir.txt
2、 API方式获取HDFS目录扩展属性信息
API方式获取HDFS目录的Extended Attributes
代码示例
package xattrstool.htsc;
import org.apache.commons.cli.*;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.security.AnnotatedSecurityInfo;
import org.apache.hadoop.security.SecurityUtil;
import org.apache.hadoop.security.UserGroupInformation;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class xattrstool {
private static String HDFSDIRPATH;
private static String KRB5FILE;
private static String PRINCIPAL;
private static String KEYPATH;
private static String CONFPATH;
public static void main(String[] args) throws IOException, InterruptedException {
//解析传入参数
Options options = new Options();
options.addOption("hdfsdir", true, "存储HDFS目录文件(*)");
options.addOption("krb5File", true, "krb5.conf配置文件绝对路径(*)");
options.addOption("keytab", true, "keytab文件绝对路径(*)");
options.addOption("principal", true, "keytab对应的主体名称(*)");
options.addOption("confPath", true, "hdfs-site.xml与core-site.xml配置文件所在目录(*)");
CommandLineParser parser = new DefaultParser();
HelpFormatter formatter = new HelpFormatter();
CommandLine commandLine = null;
try {
commandLine = parser.parse(options, args);
HDFSDIRPATH = commandLine.getOptionValue("hdfsdir");
KRB5FILE = commandLine.getOptionValue("krb5File");
KEYPATH = commandLine.getOptionValue("keytab");
PRINCIPAL = commandLine.getOptionValue("principal");
CONFPATH = commandLine.getOptionValue("confPath");
} catch (ParseException e) {
formatter.printHelp(" ", options);
System.exit(1);
}
if (args.length != 10) {
formatter.printHelp(" ", options);
System.exit(1);
}
Configuration conf = new Configuration();
//kerberos验证步骤
FileSystem fs = KerberosAuth(conf, KRB5FILE, KEYPATH, PRINCIPAL, CONFPATH);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date datestart = new Date();
String start = simpleDateFormat.format(datestart); //data -> String
System.out.println("开始时间:" + start);
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(HDFSDIRPATH), "UTF-8"));
String line = null;
Path path;
Scanner sc = new Scanner(new FileReader(HDFSDIRPATH));
while ((line = br.readLine()) != null) { //按行读取字符串
path = new Path(line);
//判断目录是否有扩展信息
if (fs.exists(path)) {
Map<String, byte[]> xAttrs = fs.getXAttrs(path);
if (!xAttrs.isEmpty()) {
Set<String> keySet = xAttrs.keySet();
for (String key : keySet) {
System.out.println("path=" + line + ",key=" + key + ",value=" + new String(xAttrs.get(key)));
}
}
}
}
fs.close();
Date dateend = new Date();
String end = simpleDateFormat.format(dateend);
System.out.println("结束时间:" + end);
System.out.println("统计花费时间:" + (dateend.getTime() - datestart.getTime()) / 1000 + "秒");
}
public static FileSystem KerberosAuth(Configuration conf, String krb5File, String keyPath, String user, String conf_path) {
FileSystem fileSystem = null;
String hdfs_path = conf_path + "hdfs-site.xml";
String core_path = conf_path + "core-site.xml";
SecurityUtil.setSecurityInfoProviders(new AnnotatedSecurityInfo());
System.setProperty("java.security.krb5.conf", krb5File);
System.setProperty("dfs.client.socket-timeout", "100");
conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");
conf.set("fs.file.impl", "org.apache.hadoop.fs.LocalFileSystem");
conf.addResource(new Path(hdfs_path));
conf.addResource(new Path(core_path));
conf.set("hadoop.security.authentication", "kerberos"); //配置认证方式
conf.set("dfs.client.use.datanode.hostname", "true");
conf.set("dfs.client.socket-timeout", "100");
UserGroupInformation.setConfiguration(conf);
try {
UserGroupInformation.loginUserFromKeytab(user, keyPath);
System.out.println("Kerberos认证成功,当前用户为:" + UserGroupInformation.getCurrentUser());
fileSystem = FileSystem.get(conf);
} catch (IOException e) {
System.out.println("Kerberos 认证失败");
e.printStackTrace();
}
return fileSystem;
}
}
MAVEN依赖
<dependencies>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
将代码进行编译打包上传到服务器中。
3、编写shell脚本
在此之前,需要准备好管理员票据keytab文件、拥有hdfs-site.xml与core-site.xml配置文件的目录,镜像文件存储目录
shell代码示例
#!/bin/bash
if [ $# != 7 ];then
echo 'usage:'
echo ' $1:执行jar的绝对路径'
echo ' $2:krb5.conf绝对路径'
echo ' $3:keytab文件路径'
echo ' $4:keytab对应的主体名称'
echo ' $5:hdfs-site.xml与core-site.xml配置文件所在目录'
echo ' $6:存储HDFS目录信息的文件绝对路径'
echo ' $7:镜像存储路径'
exit 1
fi
execjar=$1
krb5File=$2
keytab=$3
principal=$4
confPath=$5
hdfsdirfile=$6
fsimagepath=$7
if [[ ! -d ${fsimagepath} ]]; then
mkdir ${fsimagepath}
else
rm -rf ${fsimagepath}/fsimage*
fi
#提取HDFS元数据信息
hdfs dfsadmin -fetchImage ${fsimagepath}/fsimage
#以逗号分隔转换成可查看文件
hdfs oiv -i ${fsimagepath}/fsimage* -o ${fsimagepath}/hdfsfsimage.txt -p Delimited -delimiter ,
#过滤出目录文件
cat ${fsimagepath}/hdfsfsimage.txt|awk -F "," '$10 ~ "^d" {print $1}' > ${hdfsdirfile}
java -cp ${execjar} xattrstool.htsc.xattrstool -krb5File ${krb5File} -keytab ${keytab} -principal ${principal} -confPath ${confPath} -hdfsdir ${hdfsdirfile}
执行脚本命令
sh getXattrs.sh \
/root/abc/xattrstool_jar/xattrstool.jar \
/etc/krb5.conf \
/root/hdfs.keytab \
hdfs/cm111@WMM.COM \
/etc/hadoop/conf/ \
/tmp/fsimage/hdfsdir.txt \
/tmp/fsimage
#传参解释
$1:执行jar的绝对路径即上传压缩包解压后的路径
$2:krb5.conf配置文件的绝对路径"
$3:keytab文件的绝对路径(注意要有管理员权限一般为hdfs.keytab)"
$4:keytab对应的主体名称"
$5:hdfs-site.xml与core-site.xml配置文件所在绝对路径目录,注意路径末尾不能缺失/"
$6:存储HDFS目录信息文件的绝对路径"
$7:镜像存储的路径目录"
执行效果如下