hdfs工作目录 hdfs显示目录信息_npm

hdfs工作目录 hdfs显示目录信息_hadoop_02

hdfs工作目录 hdfs显示目录信息_hadoop_03

hdfs工作目录 hdfs显示目录信息_npm_04

hdfs工作目录 hdfs显示目录信息_大数据_05

官网参考链接

Extended Attributes in HDFS(简称xattrs)


本次编写目的是如何获取集群所有目录的扩展属性信息,所以概念相关的请参考官网,这里不做过多赘述。

hdfs工作目录 hdfs显示目录信息_大数据_06

HDFS的扩展属性信息简要解释

hdfs工作目录 hdfs显示目录信息_hdfs工作目录_07

这个概念其实就是额外的属性信息,通俗的理解就是HDFS目录或者文件在生成的时候会带有基础权限、用户、用户组等一些基本信息,那么我还想添加一些我认为需要备注的信息如:user.张三 values为"这个目录是张三创建的",那么通过一般的方式是做不到的,那么此时就需要HDFS的扩展属性信息技术。

截图可能更为直观一些吧

hdfs工作目录 hdfs显示目录信息_npm_08

详细解释请参考官网链接。

命令示例

#获取目录的所有扩展属性
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/

接下来的步骤就是要实现如何获取集群的目录扩展属性信息了。

hdfs工作目录 hdfs显示目录信息_hdfs_09

1、获取HDFS元数据信息

hdfs工作目录 hdfs显示目录信息_hadoop_10

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

hdfs工作目录 hdfs显示目录信息_npm_11

2、 API方式获取HDFS目录扩展属性信息

API方式获取HDFS目录的Extended Attributes

hdfs工作目录 hdfs显示目录信息_hdfs_12

代码示例

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>

将代码进行编译打包上传到服务器中。

hdfs工作目录 hdfs显示目录信息_hdfs_13

3、编写shell脚本

hdfs工作目录 hdfs显示目录信息_hdfs_14

在此之前,需要准备好管理员票据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:镜像存储的路径目录"

执行效果如下

hdfs工作目录 hdfs显示目录信息_hdfs工作目录_15

hdfs工作目录 hdfs显示目录信息_hdfs工作目录_16