首页 > 其他分享 >Hadoop基于CallerContext增强血缘信息实践

Hadoop基于CallerContext增强血缘信息实践

时间:2023-11-06 18:00:54浏览次数:35  
标签:HDFS String CallerContext Hadoop 用户 线程 血缘 null

1. 背景

一般情况下,用户会以项目为维度提交作业。因为项目用户的拥有项目下的所有权限。如下所示,个人用户bob将在project_sa项目空间下提交作业,HDFS会通过project_sa进行鉴权并访问:

Untitled.png

上述方案有一个问题,如果HDFS中的auditlog中记录的操作用户是project_us,无法分辨具体由哪个用户提交的作业。如果能够在auditlog中增加真实提交的用户,在作业相关问题时可以节省大量人力成本。

2. 方案

为了实现HDFS auditlog打印真实用户信息,需要将真实用户bob的身份信息通过计算组件传递给NameNode:

Untitled 1.png

通过调研发现,所有计算组件在访问NameNode时,都会使用FileSystem获取HDFS客户端对象。客户端在像NameNode放松RPC请求时,会携带FileSystem中的callercontext信息发送给NameNode中。因此,可以将真实用户bob信息写入到FileSystem中的callercontext中,这样namenode获取到真实用户后即可打印出来:

Untitled 2.png

3. CallerContext线程处理流程分析

首先,回忆一下在https://blog.51cto.com/u_15327484/7779462文章中,介绍了NameNode服务端的RPC的线程模型,每个RPC请求都是由一个handler线程处理的:

Untitled 3.png

同样,在客户端和服务端中,callerContext是线程级别,每一个Handler线程拥有对应rpc请求传过来的callercontext:

  private static final class CurrentCallerContextHolder {
    static final ThreadLocal<CallerContext> CALLER_CONTEXT =
        new InheritableThreadLocal<>();
  }

https://issues.apache.org/jira/browse/HDFS-9184中,新增了CallerContext特性。通过分析这个patch可以发现CallContext在服务端的处理逻辑:

  1. 服务端接收到来自客户端的Rpc请求时,从请求的header中构建服务端的一个新的CallerContext对象,放到Call对象中。
  2. 服务端从callQueue中取出请求后,创建新的Handler线程进行处理,在Handler线程中,设置Call对象中的CallerContext为当前线程的CallerContext。这样确保服务端中每个CallerContext只由一个线程处理,符合CallerContext的ThreadLocal定义。

其关键代码如下所示:

Untitled 4.png

其处理逻辑可以简化成如下流程:

Untitled 5.png

4. 代码二次开发

如下,客户端新增hadoop.caller.context.env配置,可以设置要额外打印的信息。例如额外打印Job地址信息,真实用户信息:

<property>
  <name>hadoop.caller.context.env</name>
  <value>JOB_TASKID,REAL_USER,...</value>
</property>

新增一个类,用户读取环境变量或者配置文件中设置的JOB_TASKID,REAL_USER值,写入并替换到线程对应的CallerContext中:

public class CallerContextExtension {
    private static final Logger LOG = LoggerFactory.getLogger(CallerContextExtension.class);

    public static void impoveCallerContext(Configuration conf){
        conf.addResource("hdfs-site.xml");
        CallerContext.Builder ctxBuilder = null;
        String currentContent = null;
        if(CallerContext.getCurrent() == null){
            ctxBuilder = new CallerContext.Builder(null);
        }else{
            currentContent = CallerContext.getCurrent().getContext();
            ctxBuilder = new CallerContext.Builder(currentContent);
        }
        //get env property, set Configuration, append callercontext
        String contextEnv = conf.get("hadoop.caller.context.env");
        if(contextEnv != null){
            String[] envList = contextEnv.split(",");
            for(int i = 0; i < envList.length; ++i){
                String envKey = envList[i];
                String envVal = System.getenv(envKey);
                String confVal = conf.get(envKey);
                if(confVal != null && currentContent != null && !currentContent.contains(envKey)){
                    ctxBuilder.append(envKey, confVal);
                }
            }
        }
        String newCtxText = ctxBuilder.getContext();
        String realCtx;
        int maxSize = conf.getInt("hadoop.caller.context.max.size", 128);
        if (newCtxText == null || newCtxText.length() <= maxSize) {
            realCtx = newCtxText;
        } else {
            String finalCallerContext = newCtxText.substring(0, maxSize);
            LOG.warn(
                    "Truncated Hadoop caller context from "
                            + newCtxText
                            + " to "
                            + finalCallerContext);
            realCtx = finalCallerContext;
        }
        CallerContext.setCurrent(new CallerContext.Builder(realCtx).build());
    }
}

最后,客户端在调用FileSystem.get()时,调用CallerContextExtension自动写入设置的真实用户信息:

Untitled 6.png

5. 上线测试

在客户端环境变量中增加REAL_USER信息:

export REAL_USER=gdc_sa

通过执行MR、Spark、Hive,或者直接访问HDFS,NameNode都会打印REAL_USER信息。例如,执行以下命令访问HDFS:

hdfs dfs -ls /job_1698398895366_3124388/job.split

如下所示,callercontext中打印了真实用户:

2023-11-06 17:45:18,213 INFO org.apache.hadoop.hdfs.server.namenode.FSNamesystem.audit: allowed=true    ugi=xxxx/scheduler@xxxx (auth:TOKEN)        ip=/xxxxxx        cmd=open        src=/job_1698398895366_3124388/job.split    dst=null        perm=null       proto=rpc       callerContext=REAL_USER:gdc_sa

标签:HDFS,String,CallerContext,Hadoop,用户,线程,血缘,null
From: https://blog.51cto.com/u_15327484/8215506

相关文章

  • Hadoop整合AWS S3和Google gcs对象存储实践
    1.背景https://blog.51cto.com/u_15327484/8193991介绍了海外Hadoop集群一般将冷数据放入到AWSS3或者存放到Googlegcs对象存储中。这些对象存储都提供了各自的客户端进行访问,例如awss3的客户端命令就是awss3;gcs的客户端命令是gsutil。这些命令一般需要直接登陆到授权机器中执......
  • Kerberos在Hadoop中的应用
    1.背景在https://blog.51cto.com/u_15327484/8153877文章中,介绍了在Java中,客户端通过JAAS框架向AS认证获取TGT,再通过GSSAPIonSASL获取serviceticket并向服务端进行认证。Hadoop中整合Kerberos安全认证机制,当HDFS客户端访问NameNode服务端时,HDFS客户端先获取TGT,再获取service......
  • Hadoop-3.3.3分布式集群的文件配置,启动hadoop历史服务和启动日志聚集
    一、分布式集群的文件配置涉及$HADOOP_HOME/etc/hadoop路径下的5个文件workers、core-site.xml、hdfs-site.xml、mapred-site.xml、yarn-site.xml首先修改workers进入$HADOOP_HOME/etc/hadoopvimworkers编辑自己的主机节点。注意!每行一个,默认为把本机节点同时作为数据节......
  • 云计算-hadoop的安装(书接上回+分布式搭建)
    书接上回,这次来进行分布式集群的搭建。 执行命令:echo$JAVA_HOME查看路径,我的路径如图所示:  然后在/usr/local/hadoop目录下,执行命令gedit./etc/hadoop/hadoop-env.sh打开文本,然后再第一行添加刚刚的路径,如图所示:  因为之前一节咱们已经配置过hdfs-site.xml和co......
  • hadoop 基础组件详解
           ......
  • hadoop初体验1——官方案例pi值计算
    1.执行命令[hadoop@namenodemapreduce]$hadoopjarhadoop-mapreduce-examples-3.3.6.jarpi22hadoopjarHadoopjar命令hadoop-mapreduce-examples-3.3.6.jar程序所在jar包pi22——参数2.执行信息NumberofMaps=2SamplesperMap=2WroteinputforMap#0......
  • Hadoop三大组件(HDFS,MapReduce,Yarn)
    1、HDFSHDFS是Hadoop分布式文件系统。一个HDFS集群是由一个NameNode和若干个DataNode组成的。其中NameNode作为主服务器,管理文件系统的命名空间和客户端对文件的访问操作;集群中的DataNode管理存储的数据。2、MapReduceMapReduce是一个软件框架,基于该框架能够容易地编写......
  • window10安装单机hadoop
    一、配置jdk默认已配置二、下载hadoop3.2.2http://archive.apache.org/dist/hadoop/common/hadoop-3.2.2/三、下载hadoop-winutilshttps://github.com/cdarlint/winutils下载后将bin中的文件全部放到hadoop/bin中四、配置hadoop1、进入hadoop安装文件夹下的etc/hadoop......
  • 云计算-hadoop的安装
    云计算的课程,主要还是要梳理逻辑(尽管我不是做这个方向的,但是课程还是要好好完成!)前提:安装好虚拟机VirtualBox,并且下载好Ubuntu的光盘映像文件。文章思路:1.配环境(SSH免密码登录,JAVA环境)2.配Hadoop(下载包,配置相应的环境)3.运行(感受一下实际例子)  1.配环境1.1前期用户等的配置......
  • Hadoop-大数据组件版本号查看
    1.操作系统cat /etc/redhat-release; 2.JDKjava-version 3.SCALAscala --version 4.MySQLmysql--version 5.Zookeeperps-ef|grep-E“zookeeper-.*.jar” 6.Hadoophadoopversion 7.Hivehive --version 8.Hbasehbaseversion 9.Sparkspark-subm......