Hive获取最大分区

需求:
需要在hive的SQL语句中使用函数来解析指定表的最大分区

倘若我们使用 select max(pt) from ods. ods_tb_customer_df 的方式去获取最大分区还需启动一个map任务进行计算,我本地测试的结果,一次这样的计算需要Time taken: 73.849 seconds ,简直不能忍,所以需要寻求更好的方式。

我们知道hive中有HiveMetaStoreClient api 可以直接获取分区数据,省去了中间环节,效率大增,具体可以参考 http://hive.apache.org/javadocs/r2.1.1/api/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.html

但是,我们的集群是有kerberos认证的,所以在经过一些列的失败尝试后将如下解决方案记录下来:

HIVE UDF :max_pt

@Description(name = "max_pt", value = "_FUNC_(db,table) - return the max partition")
public class MaxPt extends UDF {
    String uris = "thrift://xxx:9083";

    public String evaluate(String db, String table) throws IOException, TException {
        if (StringUtils.isEmpty(db) || StringUtils.isEmpty(table)) {
            return "";
        }

        String confPath = "/etc/krb5.conf";
        System.setProperty("java.security.krb5.conf", confPath);
        System.setProperty("HADOOP_USER_NAME", "xx");
        System.setProperty("user.name", "xxx");
        Configuration conf = new Configuration();
        conf.set("hadoop.security.authentication", "Kerberos");
        UserGroupInformation.setConfiguration(conf);


        String keyPath = "/etc/xxx.keytab";
        UserGroupInformation.loginUserFromKeytab("xxx", keyPath);
        HiveConf hiveConf = new HiveConf();
        hiveConf.setVar(HiveConf.ConfVars.METASTOREURIS, uris);
        IMetaStoreClient client = new HiveMetaStoreClient(hiveConf);
        List<Partition> listPartitions = client.listPartitions(db, table, Short.MAX_VALUE);
        return Collections.max(listPartitions).getValues().get(0);
    }
}

hive客户端执行,注册永久函数:

create  function max_pt AS 'com.function.udf.MaxPt' using jar 'hdfs://nameservice1/user/lib/max_pt.jar';

加载函数:

reload functions;

使用函数:

select max_pt("ods","test_01");

此外需要注意:krb5.conf,和xx,keytab文件我在项目中使用相对路径是无法认证通过的,所以将其放在/etc目录下。

你可能感兴趣的:(Hadoop,hive)