HiveMetaStoreClient常见用法

232 阅读6分钟

HiveMetaStoreClient 是 Apache Hive 提供的一个用于操作 Hive 元数据的 Java API 客户端。它允许你通过 Java 代码与 Hive 的元数据存储进行交互,执行诸如创建表、删除表、添加分区、删除分区等操作。以下是 HiveMetaStoreClient 主要 API 的使用总结和说明:

构造函数

HiveMetaStoreClient(HiveConf conf) throws MetaException

  • 描述: 创建一个新的 HiveMetaStoreClient 实例。
  • 参数:
    • conf: HiveConf 对象,包含 Hive 的配置信息。
  • 异常:
    • MetaException: 如果无法连接到元数据服务或元数据服务发生其他错误。

元数据操作

获取数据库列表

  • 方法: List<String> getAllDatabases() throws MetaException, TException
  • 描述: 获取所有数据库的名称。
  • 异常:
    • MetaException: 如果元数据服务发生错误。
    • TException: 如果 Thrift 通信发生错误。

获取表列表

  • 方法: List<String> getAllTables(String dbName) throws MetaException, TException
  • 描述: 获取指定数据库中所有表的名称。
  • 参数:
    • dbName: 要获取表列表的数据库名称。
  • 异常:
    • MetaException: 如果元数据服务发生错误。
    • TException: 如果 Thrift 通信发生错误。

获取表对象

  • 方法: Table getTable(String dbName, String tableName) throws MetaException, NoSuchObjectException, TException
  • 描述: 获取指定表的元数据信息。
  • 参数:
    • dbName: 表所在的数据库名称。
    • tableName: 表名称。
  • 异常:
    • MetaException: 如果元数据服务发生错误。
    • NoSuchObjectException: 如果指定的数据库或表不存在。
    • TException: 如果 Thrift 通信发生错误。

创建表

  • 方法: void createTable(Table table) throws AlreadyExistsException, InvalidObjectException, MetaException, NoSuchObjectException, TException
  • 描述: 创建新表。
  • 参数:
    • table: 要创建的表的元数据信息。
  • 异常:
    • AlreadyExistsException: 如果要创建的表已经存在。
    • InvalidObjectException: 如果提供的表元数据信息无效。
    • MetaException: 如果元数据服务发生错误。
    • NoSuchObjectException: 如果指定的数据库不存在。
    • TException: 如果 Thrift 通信发生错误。

删除表

  • 方法: void dropTable(String dbName, String tableName, boolean deleteData) throws NoSuchObjectException, MetaException, TException
  • 描述: 删除指定的表。
  • 参数:
    • dbName: 表所在的数据库名称。
    • tableName: 表名称。
    • deleteData: 是否同时删除表对应的数据。
  • 异常:
    • NoSuchObjectException: 如果指定的数据库或表不存在。
    • MetaException: 如果元数据服务发生错误。
    • TException: 如果 Thrift 通信发生错误。

添加分区

  • 方法: void addPartition(Partition partition) throws InvalidObjectException, AlreadyExistsException, MetaException, TException
  • 描述: 向表中添加新的分区。
  • 参数:
    • partition: 要添加的分区的元数据信息。
  • 异常:
    • InvalidObjectException: 如果提供的分区元数据信息无效。
    • AlreadyExistsException: 如果要添加的分区已经存在。
    • MetaException: 如果元数据服务发生错误。
    • TException: 如果 Thrift 通信发生错误。

删除分区

  • 方法: void dropPartition(String dbName, String tableName, List<String> partVals, boolean deleteData) throws NoSuchObjectException, MetaException, TException
  • 描述: 删除指定表的指定分区。
  • 参数:
    • dbName: 表所在的数据库名称。
    • tableName: 表名称。
    • partVals: 分区值列表。
    • deleteData: 是否同时删除分区对应的数据。
  • 异常:
    • NoSuchObjectException: 如果指定的数据库、表或分区不存在。
    • MetaException: 如果元数据服务发生错误。
    • TException: 如果 Thrift 通信发生错误。

其他操作

关闭客户端连接

  • 方法: void close()
  • 描述: 关闭与 HiveMetaStore 的连接,释放资源。

修改表

更新表元数据

  • 方法: void alter_table(String dbName, String tblName, Table new_tbl) throws InvalidOperationException, MetaException, TException
  • 描述: 更新表的元数据,可以修改表的属性,例如修改表的位置等。
  • 参数:
    • dbName: 表所在的数据库名称。
    • tblName: 表名称。
    • new_tbl: 新的表元数据信息。
  • 异常:
    • InvalidOperationException: 如果操作无效,例如尝试创建已经存在的表。
    • MetaException: 如果元数据服务发生错误。
    • TException: 如果 Thrift 通信发生错误。

获取分区信息

获取指定表的所有分区

  • 方法: List<Partition> listPartitions(String dbName, String tblName, short max_parts) throws MetaException, NoSuchObjectException, TException
  • 描述: 获取指定表的所有分区的元数据信息。
  • 参数:
    • dbName: 表所在的数据库名称。
    • tblName: 表名称。
    • max_parts: 最大返回分区数,-1 表示不限制。
  • 异常:
    • MetaException: 如果元数据服务发生错误。
    • NoSuchObjectException: 如果指定的数据库或表不存在。
    • TException: 如果 Thrift 通信发生错误。

根据过滤条件获取分区

  • 方法: List<Partition> listPartitionsByFilter(String dbName, String tblName, String filter, short max_parts) throws MetaException, NoSuchObjectException, TException
  • 描述: 根据过滤条件获取指定表的分区的元数据信息。
  • 参数:
    • dbName: 表所在的数据库名称。
    • tblName: 表名称。
    • filter: 过滤条件,可以使用 Hive 的分区查询语法。
    • max_parts: 最大返回分区数,-1 表示不限制。
  • 异常:
    • MetaException: 如果元数据服务发生错误。
    • NoSuchObjectException: 如果指定的数据库或表不存在。
    • TException: 如果 Thrift 通信发生错误。

元数据同步

复制表的元数据

  • 方法: void copyTable(String srcDatabase, String srcTable, String destDatabase, String destTable, boolean external, boolean ignoreProtection) throws MetaException, NoSuchObjectException, AlreadyExistsException, TException
  • 描述: 复制表的元数据信息,可以将表从一个数据库复制到另一个数据库。
  • 参数:
    • srcDatabase: 源表所在的数据库名称。
    • srcTable: 源表名称。
    • destDatabase: 目标表所在的数据库名称。
    • destTable: 目标表名称。
    • external: 是否复制为外部表。
    • ignoreProtection: 是否忽略保护设置。
  • 异常:
    • MetaException: 如果元数据服务发生错误。
    • NoSuchObjectException: 如果源表不存在。
    • AlreadyExistsException: 如果目标表已经存在。
    • TException: 如果 Thrift 通信发生错误。

其他操作

获取 Hive 配置

  • 方法: HiveConf getHiveConf()
  • 描述: 获取当前 HiveMetaStoreClient 实例的 Hive 配置信息。

总结

HiveMetaStoreClient 提供了丰富的 API,可以实现对 Hive 元数据的各种操作,包括管理数据库、表、分区等。通过这些 API,你可以在 Java 程序中轻松地操作 Hive 元数据,完成各种元数据管理任务。在使用时,务必注意异常处理,以确保操作的稳定性和可靠性。

案例

如果是多集群,只要在resource下配置不同名的hive-site.xml文件即可,这样可以创建不同的客户端,默认是加载名为hive-site.xml配置文件

删除分区案例

import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.HiveMetaStoreClient;
import org.apache.hadoop.hive.metastore.api.MetaException;
import org.apache.hadoop.hive.metastore.api.NoSuchObjectException;
import org.apache.thrift.TException;

public class DropPartitionExample {
    public static void main(String[] args) {
        // Hive 配置文件路径
        String hiveSitePath = "hive-site.xml";

        // 数据库名和表名
        String dbName = "your_db_name";
        String tableName = "your_table_name";

        // 分区名称
        String partName = "pt=20240506";

        try {
            // 创建 HiveConf 对象并加载配置文件
            HiveConf hiveConf = new HiveConf();
            hiveConf.addResource(hiveSitePath);

            // 创建 HiveMetaStoreClient 对象
            HiveMetaStoreClient client = new HiveMetaStoreClient(hiveConf);

            // 删除分区
            client.dropPartition(dbName, tableName, partName, false);

            // 关闭 HiveMetaStoreClient
            client.close();

            System.out.println("Partition deleted successfully.");
        } catch (NoSuchObjectException | MetaException | TException e) {
            e.printStackTrace();
        }
    }
}

多客户端案例

package com.bigdata.meta;

import lombok.extern.slf4j.Slf4j;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.HiveMetaStoreClient;
import org.apache.hadoop.hive.metastore.api.Partition;
import org.apache.hadoop.hive.metastore.api.StorageDescriptor;
import org.apache.hadoop.hive.metastore.api.Table;
import org.apache.hadoop.security.UserGroupInformation;

import java.util.ArrayList;
import java.util.List;

/**
 * @author mayishijie
 * @version 1.0  2024/6/6 1:37 PM
 */
@Slf4j
public class ClientTest {
    public static void main(String[] args) {
        System.setProperty("HADOOP_USER_NAME", "root");
        HiveMetaStoreClient client2 = null;
        HiveMetaStoreClient client3 = null;
        try {

            HiveConf conf2 = new HiveConf();
            HiveConf conf3 = new HiveConf();
            conf2.addResource("hive2-site.xml");
            conf3.addResource("hive3-site.xml");
            client2 = new HiveMetaStoreClient(conf2);
            client3 = new HiveMetaStoreClient(conf3);

//            List<String> allTables = client2.getAllTables("i8ji");
//            allTables.forEach(System.out::println);
//            log.info("=================");
//            List<String> p1List = client2.listPartitionNames("i8ji", "partition_test_001", (short) -1);
//            log.info("p1List===>{}", p1List.size());
//            List<String> p2List = client2.listPartitionNames("i8ji", "partition_test_002", (short) -1);
//            log.info("p2List===>{}", p2List.size());

//            Table table = client2.getTable("i8ji", "test001");
//            log.info("old table===>{}", table);
//            StorageDescriptor sd = table.getSd();
//            sd.setLocation("hdfs://mycluster/user/hive3/warehouse/i8ji.db/partition_test_001/pt=1");
//            client2.alter_table("i8ji", "test001", table);
//            log.info("new table===>{}", table);

            Partition partition = client2.getPartition("i8ji", "partition_test_002", "pt=1499");
            log.info("old partiton1=>{}", partition);
            Partition addPartiton = partition.deepCopy();
            List<String> drop = new ArrayList<>();
            drop.add("pt=1499");
            client2.dropPartition("i8ji", "partition_test_002", "pt=1499", true);
            log.info("分区删除成功");
            client2.add_partition(addPartiton);
            log.info("新增分区成功");
            Partition dropPartition = client2.getPartition("i8ji", "partition_test_002", "pt=1500");
            log.info("dropPartition={}",dropPartition);
            Partition addPartition = client2.getPartition("i8ji", "partition_test_002", "pt=1500");
            log.info("addPartition={}",addPartition);


//            partition.getSd().setLocation("hdfs://mycluster/user/hive3/warehouse/i8ji.db/partition_test_001/pt=1502");


            List<String> ptList = new ArrayList<>();
            ptList.add("pt=2");
            List<Partition> partitionsByNames = client2.getPartitionsByNames("i8ji", "partition_test_002", ptList);

//            client2.getTable("i8ji", "partition_test_002").getpa
            log.info("old partiton2=>{}", partitionsByNames.get(0));


        }catch (Exception e){
            log.error("e===>",e);
        }finally {
            if (client2!=null) {
                client2.close();
            }
            if (client3!=null) {
                client3.close();
            }
            log.info("资源释放成功");
        }
    }
}