本文作者:刘勋,有着十七年的软件行业和互联网行业的开发和架构经验,目前在网易杭州研究院大数据部门从事猛犸大数据平台的 hadoop 开发工作。
在网易集团内部有大大小小几百套 hive 集群,为了满足网易猛犸大数据平台的元数据统一管理的需求,我们需要将多个分别独立的 hive 集群的元数据信息进行合并,但是不需要移动 HDFS 中的数据文件,比如可以将 hive2、hive3、hive4 的元数据全部合并到 hive1 的元数据 Mysql 中,然后就可以在 hive1 中处理 hive2、hive3、hive4 中的数据。
我们首先想到的是 hive 中有自带的 EXPORT 命令,可以把指定库表的数据和元数据导出到本地或者 HDFS 目录中,再通过 IMPORT 命令将元数据和数据文件导入新的 hive 仓库中,但是存在以下问题不符合我们的场景
于是我们便考虑自己开发一个 hive 元数据迁移合并工具,满足我们的以下需求:
hive 的元数据信息(metastore)一般是通过 Mysql 数据库进行存储的,在 hive-1.2.1 版本中元数据信息有 54 张表进行了存储,比如存储了数据库名称的表 DBS
、存储表名称的表 TBLS
、分区信息的 PARTITIONS
等等。
元数据信息的这 54 张表通过 ID
号形成的很强的主外健依赖关系,例如
DBS
表中的 DB_ID
字段被 20 多张表作为外健进行了引用;TBLS
表中的 TBL_ID
字段被 20 多张表作为外健进行了引用;TBLS
表中的 DB_ID
字段是 DBS
表的外健、SD_ID
字段是 SDS
表的外健;PARTITIONS
表中的 TBL_ID
字段是 TBLS
表的外健、SD_ID
字段是 SDS
表的外健;DATABASE_PARAMS
表中的 DB_ID
字段是 DBS
表的外健;这样的嵌套让表与表之间的关系表现为 [DBS]=>[TBLS]=>[PARTITIONS]=>[PARTITION_KEY_VALS],像这样具有 5 层以上嵌套关系的有4-5 套,这为元数据合并带来了如下问题。
我们使用了一个巧妙的方法来解决 ID 修改的问题:
我们使用了 mybatis 进行了源和目标这 2 个 Mysql 的数据库操作,从源 Mysql 中按照上面的逻辑关系取出元数据修改主外健的 ID 号再插入到目标 Mysql 数据库中。
druid
解析 hive 的建表语句,再通过 codemodel
自动生成出了对应每个表的 54 个 JAVA 类对象。参见代码:com.netease.hivetools.apps.SchemaToMetaBean
第一步:备份元数据迁移前的目标和源数据库
第二步:将源数据库的元数据导入到临时数据库 exchange_db 中,需要一个临时数据库是因为源数据库的 hive 集群仍然在提供在线服务,元数据表的 ID 流水号仍然在变化,hive-tools 工具只支持目的数据库是在线状态;
通过临时数据库 exchange_db 能够删除多余 hive db 的目的,还能够通过固定的数据库名称,规范整个元数据迁移操作流程,减低因为手工修改执行命令参数导致出错的概率
在 hive-tools.properties 文件中中配置源和目的数据库的 JDBC 配置项
# exchange_db
exchange_db.jdbc.driverClassName=com.mysql.jdbc.Driver
exchange_db.jdbc.url=jdbc:mysql://10.172.121.126:3306/hivecluster1?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
exchange_db.jdbc.username=src_hive
exchange_db.jdbc.password=abcdefg
# dest_hive
dest_hive.jdbc.driverClassName=com.mysql.jdbc.Driver
dest_hive.jdbc.url=jdbc:mysql://10.172.121.126:3306/hivecluster1?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
dest_hive.jdbc.username=dest_hive
dest_hive.jdbc.password=abcdefg
执行元数据迁移命令
export SOURCE_NAME=exchange_db
export DEST_NAME=dest_hive
/home/hadoop/java-current/jre/bin/java -cp "./hive-tools-current.jar" com.netease.hivetools.apps.MetaDataMerge --s=$SOURCE_NAME --d=$DEST_NAME
hive-tools 会在迁移元数据之前首先检查源和目的元数据库中重名的 hive db,终止元数据迁移操作并给出提示
执行删除重名数据库命令
# 修改脚本中的 DEL_DB(多个库之间用逗号分割,default必须删除)参数和 DEL_TBL(为空则删除所有表)
export SOURCE=exchange_db
export DEL_DB=default,nisp_nhids,real,azkaban_autotest_db
export DEL_TBL=
~/java-current/jre/bin/java -cp "./hive-tools-current.jar" com.netease.hivetools.apps.DelMetaData --s=$SOURCE --d=$DEL_DB --t=$DEL_TBL
再次执行执行元数据迁移命令
检查元数据迁移命令窗口日志或文件日志,如果发现元数据合并出错,通过对目的数据库进行执行删除指定 hive db 的命令,将迁移过去的元数据进行删除,如果没有错误,通过 hive 客户端检查目的数据库中是否能够正常使用新迁移过来的元数据
严格按照我们的元数据迁移流程已经在网易集团内部通过 hive-tools 已经成功迁移合并了大量的 hive 元数据库,没有出现过问题。
hive-tools 项目地址:https://github.com/NetEase/hive-tools