Hive代码分析报告(十三):metastore模块分析①

2021SC@SDUSC

目录

概述

代码分析

MetaStoreClient客户端的创建


概述

前面分析主要是cli用户接口和driver编译器部分。下面我将对hive的metastore模块进行分析。

hive metastore 是什么呢?

它是一个服务端,简称server。默认的端口为9083

有什么作用呢?

作用是建立起和hive客户端的连接,当客户端来请求,server去远程metastore数据库查询信息返回。

代码分析

Metastore模块在metastore目录下

该模块主要分为两个部分

HiveMetaStoreClient

 是Hive连接MetaStore的客户端。HiveMetaStoreClient可以通过本地和远程两种方式访问和调用HiveMetaStore的Server。

HiveMetaStore

     HiveMetaStore是HiveMetaStoreClient的服务端,可能与HiveMetaStoreClient在同一台服务器上,也可以不再统一服务器上。但是HiveMetaStore一定与实际存储Meta信息的数据库在一台服务器上。

MetaStoreClient客户端的创建

先看以下代码

private HiveConf conf = null;

  private IMetaStoreClient metaStoreClient;

  private UserGroupInformation owner;


  // metastore calls timing information

  private final Map<String, Long> metaCallTimeMap = new HashMap<String, Long>();


  private static ThreadLocal<Hive> hiveDB = new ThreadLocal<Hive>() {

    @Override

    protected synchronized Hive initialValue() {

      return null;

    }


    @Override

    public synchronized void remove() {

      if (this.get() != null) {

        this.get().close();

      }

      super.remove();

    }

  };

这里声明的有hiveConf对象、metaStoreClient 、操作用户组userGroupInfomation以及调用时间Map,这里存成一个map,用来记录每一个动作的运行时长。同时维护了一个本地线程hiveDB,如果db为空的情况下,会重新创建一个Hive对象,代码如下:

public static Hive get(HiveConf c, boolean needsRefresh) throws HiveException {

    Hive db = hiveDB.get();

    if (db == null || needsRefresh || !db.isCurrentUserOwner()) {

      if (db != null) {

        LOG.debug("Creating new db. db = " + db + ", needsRefresh = " + needsRefresh +

          ", db.isCurrentUserOwner = " + db.isCurrentUserOwner());

      }

      closeCurrent();

      c.set("fs.scheme.class", "dfs");

      Hive newdb = new Hive(c);

      hiveDB.set(newdb);

      return newdb;

    }

    db.conf = c;

    return db;

  }

随后我们会发现,在创建Hive对象时,便已经将function进行注册,什么是function呢,通过上次的表结构分析,可以理解为所有udf等jar包的元数据存储。代码和解析如下:

// register all permanent functions. need improvement

  static {

    try {

      reloadFunctions();

    } catch (Exception e) {

      LOG.warn("Failed to access metastore. This class should not accessed in runtime.",e);

    }

  }


  public static void reloadFunctions() throws HiveException {    

//获取 Hive对象,用于后续方法的调用

Hive db = Hive.get();    

//通过遍历每一个dbName

for (String dbName : db.getAllDatabases()) {     

 //通过dbName查询挂在该db下的所有function的信息。

      for (String functionName : db.getFunctions(dbName, "*")) {

        Function function = db.getFunction(dbName, functionName);

        try {     

//这里的register便是将查询到的function的数据注册到Registry类中的一个Map<String,FunctionInfo>中,以便计算引擎在调用时,不必再次查询数据库。

      FunctionRegistry.registerPermanentFunction(

          FunctionUtils.qualifyFunctionName(functionName, dbName), function.getClassName(),

          false, FunctionTask.toFunctionResource(function.getResourceUris()));

        } catch (Exception e) {

          LOG.warn("Failed to register persistent function " +

              functionName + ":" + function.getClassName() + ". Ignore and continue.");

        }

      }

    }

  }

调用getMSC()方法,进行metadataClient客户端的创建,代码如下:
  

private IMetaStoreClient createMetaStoreClient() throws MetaException {


    //这里实现接口HiveMetaHookLoader

      HiveMetaHookLoader hookLoader = new HiveMetaHookLoader() {

          @Override

          public HiveMetaHook getHook(

            org.apache.hadoop.hive.metastore.api.Table tbl)

            throws MetaException {


            try {

             if (tbl == null) {

               return null;

             }

     //根据tble的kv属性加载不同storage的实例,比如hbase、redis等等拓展存储,作为外部表进行存储

             HiveStorageHandler storageHandler =

               HiveUtils.getStorageHandler(conf,

                 tbl.getParameters().get(META_TABLE_STORAGE));

             if (storageHandler == null) {

               return null;

             }

             return storageHandler.getMetaHook();

           } catch (HiveException ex) {

             LOG.error(StringUtils.stringifyException(ex));

             throw new MetaException(

               "Failed to load storage handler:  " + ex.getMessage());

           }

         }

       };

     return RetryingMetaStoreClient.getProxy(conf, hookLoader, metaCallTimeMap,

        SessionHiveMetaStoreClient.class.getName());

   }

以上就是MetaStoreClient的简单创建流程的分析。

下一篇,我将分析服务端创建的步骤。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值