本文档描述了怎样把 Hive 数据库从一个 Hadoop 集群迁移到另一个 Hadoop 集群。
本文档假定新集群的 Hive 元数据库的内容可以清空。
停止方法:使用命令systemctl stop hive-metastore
或者通过 ambari 操作。
systemctl stop hive-metastore
systemctl stop hive-server2
停止 hive metastore 后,集群所有的访问 hive 的任务都会报错。
systemctl stop hive-metastore
systemctl stop hive-server2
mysqldump -h ${MYSQL_HOST} -uhive '-p${MYSQL_PASSWD}' hive > hive-metastore.bak
登录新的数据库
mysql -h ${NEW_MYSQL_HOST} -uhive '-p${MYSQL_PASSWD}' hive
如果目标数据库已经存在则先删除
drop database hive;
创建目标数据库
create database hive;
导入数据到新的数据库。
mysql -h ${NEW_MYSQL_HOST} -uhive '-p${MYSQL_PASSWD}' hive < hive-metastore.bak
${NEW_MYSQL_HOST} 是数据库新的地址。
按需要修改以下配置,如果 MYSQL 数据库信息没有改变,则不需要修改。
<property>
<name>javax.jdo.option.ConnectionDriverNamename>
<value>com.mysql.jdbc.Drivervalue>
property>
<property>
<name>javax.jdo.option.ConnectionPasswordname>
<value>${MYSQL_PASSWD}value>
property>
<property>
<name>javax.jdo.option.ConnectionURLname>
<value>jdbc:mysql://${NEW_MYSQL_HOST}/hive?createDatabaseIfNotExist=true&characterEncoding=UTF-8value>
property>
<property>
<name>javax.jdo.option.ConnectionUserNamename>
<value>hivevalue>
property>
如果新集群的 Hive 版本比老集群的 Hive 版本新,执行此步骤。如果一致,则跳过此步骤。新集群的 Hive 版本不得小于老集群的 Hive 版本。
在新集群 metastore 所在服务器,使用 hive 用户下执行以下操作, ${NEW_MYSQL_HOST}是新 mysql 数据库所在的服务器 IP 地址。
如下是把 hive 从 1.2 升级到 3.1。
cd /opt/bmr/hive/scripts/metastore/upgrade/mysql
mysql -uhive '-p${MYSQL_PASSWD}' -h ${NEW_MYSQL_HOST} hive
进入 MYSQL 之后,执行以下 SQL 命令。
source upgrade-1.2.0-to-2.0.0.mysql.sql;
source upgrade-2.0.0-to-2.1.0.mysql.sql;
source upgrade-2.1.0-to-2.2.0.mysql.sql;
source upgrade-2.2.0-to-2.3.0.mysql.sql;
source upgrade-2.3.0-to-3.0.0.mysql.sql;
source upgrade-3.0.0-to-3.1.0.mysql.sql;
此步骤要求所有管理表都在老集群参数hive.metastore.warehouse.dir
设置的目录下。
<property>
<name>hive.metastore.warehouse.dirname>
<value>/warehouse/tablespace/managed/hivevalue>
property>
执行命令:
hadoop fs -rm -r hdfs://${new-cluster}/${hive.metastore.warehouse.dir}
hadoop distcp hdfs://${old-cluster}/${hive.metastore.warehouse.dir} hdfs://${new-cluster}/${hive.metastore.warehouse.dir
注意:目标路径 hdfs:// n e w − c l u s t e r / {new-cluster}/ new−cluster/{hive.metastore.warehouse.dir} 必须不存在,否则会拷贝到它的子目录。
一般在新集群中执行 distcp 命令。如果在新集群执行 distcp 命令,需要在新集群设置老集群的配置, 并且所有新集群的服务器需要识别老集群的服务器,反之亦然。
如果不能用 hdfs 协议访问老集群,可以使用 hftp 或者 webhdfs 协议。
此步骤要求所有管理表都在老集群参数hive.metastore.warehouse.external.dir
设置的目录下,或者统一的目录。
<property>
<name>hive.metastore.warehouse.external.dirname>
<value>/warehouse/tablespace/external/hivevalue>
property>
执行命令:
hadoop fs -rm -r hdfs://${new-cluster}/${hive.metastore.warehouse.external.dir}
hadoop distcp hdfs://${old-cluster}/${hive.metastore.warehouse.external.dir} hdfs://${new-cluster}/${hive.metastore.warehouse.external.dir}
一般在新集群中执行 distcp 命令。如果在新集群执行 distcp 命令,需要在新集群设置老集群的配置, 并且所有新集群的服务器需要识别老集群的服务器,反之亦然。
如果不能用 hdfs 协议访问老集群,可以使用 hftp 或者 webhdfs 协议。
mysql -h 172.18.0.148 -uhive ‘-p*Hive123’ hive
-- managed db location
update DBS SET DB_LOCATION_URI=replace(DB_LOCATION_URI, 'hdfs://${old-cluster}/${hive.metastore.warehouse.dir}','hdfs://${new-cluster}/${hive.metastore.warehouse.dir}');
-- external db location
update DBS SET DB_LOCATION_URI=replace(DB_LOCATION_URI, 'hdfs://${old-cluster}/${hive.metastore.warehouse.external.dir}', 'hdfs://${new-cluster}/${hive.metastore.warehouse.external.dir}' );
-- managed table and partition location
UPDATE SDS SET LOCATION = REPLACE(LOCATION, 'hdfs://${old-cluster}/${hive.metastore.warehouse.dir}','hdfs://${new-cluster}/${hive.metastore.warehouse.dir}');
-- external table partition location
update SDS SET LOCATION=replace(LOCATION, 'hdfs://${old-cluster}/${hive.metastore.warehouse.external.dir}', 'hdfs://${new-cluster}/${hive.metastore.warehouse.external.dir}');
进入新集群的 metastore 和 hiveserver 对应的服务器,以 root 身份执行以下命令。
systemctl start hive-metastore;
systemctl start hive-server2;
查询老集群的表,看数据是否正确。
老集群 hdfs 地址为:hdfs://master-9331fa9:8020,hive 版本为 hive 1.2.0,mysql 元数据库地址为 master-9331fa9
新集群 hdfs 地址为:hdfs://master-b882990:8020,hive 版本为 hive 3.1.0,mysql 元数据库地址为 master-b882990(IP:172.18.0.148)
create database managed;
use managed;
create table t(c1 string) stored as textfile;
load data local inpath '/etc/profile' overwrite into table t;
create table tp(c1 string) partitioned by (pt string)stored as textfile;
load data local inpath '/etc/profile' overwrite into table tp partition(pt='profile');
create database e_db location '/warehouse/tablespace/external/hive/e_db.db';
use e_db;
create table e(c1 string) stored as textfile;
load data local inpath '/etc/hosts' overwrite into table e;
create table ep(c1 string) partitioned by (pt string)stored as textfile;
load data local inpath '/etc/hosts' overwrite into table ep partition(pt='hosts');
在老集群的 master-9331fa9 的 root 账号执行以下命令:
systemctl stop hive-metastore
systemctl stop hive-server2
在老集群的 master-b882990 的 root 账号执行以下命令:
systemctl stop hive-metastore
systemctl stop hive-server2
mysqldump -h master-9331fa9 -uhive '-p*Hive123' hive > hive-metastore.bak
登录新的数据库
mysql -h 172.18.0.148 -uhive '-p*Hive123' hive
目标数据库已经存在,先删除
drop database hive;
创建目标数据库
create database hive;
恢复 MYSQL:
mysql -h 172.18.0.148 -uhive '-p*Hive123' hive < hive-metastore.bak
新集群连接 MYSQL 数据库的地址没有改变,跳过此步。
如下是把 hive 从 1.2 升级到 3.1。
cd /opt/bmr/hive/scripts/metastore/upgrade/mysql
mysql -h 172.18.0.148 -uhive '-p*Hive123' hive
进入 MYSQL 之后,执行以下 SQL 命令。
source upgrade-1.2.0-to-2.0.0.mysql.sql;
source upgrade-2.0.0-to-2.1.0.mysql.sql;
source upgrade-2.1.0-to-2.2.0.mysql.sql;
source upgrade-2.2.0-to-2.3.0.mysql.sql;
source upgrade-2.3.0-to-3.0.0.mysql.sql;
source upgrade-3.0.0-to-3.1.0.mysql.sql;
quit;
把老集群的 /etc/hosts 的内容负责到新集群所有服务器的 /etc/hosts 中。
以 hive 账号执行以下命令
hadoop fs -rm -r hdfs://master-b882990/warehouse/tablespace/managed/hive
hadoop distcp hdfs://master-9331fa9:8020/apps/hive/warehouse hdfs://master-b882990:8020/warehouse/tablespace/managed/
以 hive 账号执行以下命令:
hadoop fs -rm -r /warehouse/tablespace/external/hive
hadoop distcp hdfs://master-9331fa9:8020/warehouse/tablespace/external/hive hdfs://master-b882990:8020/warehouse/tablespace/external/hive
mysql -h 172.18.0.148 -uhive '-p*Hive123' hive
进入 MYSQL 环境执行以下命令:
-- managed db location
update DBS SET DB_LOCATION_URI=replace(DB_LOCATION_URI, 'hdfs://master-9331fa9:8020/apps/hive/warehouse','hdfs://master-b882990:8020//warehouse/tablespace/managed/hive');
-- external db location
update DBS SET DB_LOCATION_URI=replace(DB_LOCATION_URI, 'hdfs://master-9331fa9:8020/warehouse/tablespace/external/hive','hdfs://master-b882990:8020/warehouse/tablespace/external/hive');
-- managed table and partition location
UPDATE SDS SET LOCATION = REPLACE(LOCATION, 'hdfs://master-9331fa9:8020/apps/hive/warehouse','hdfs://master-b882990:8020/warehouse/tablespace/managed/hive');
-- external table partition location
update SDS SET LOCATION=replace(LOCATION, 'hdfs://master-9331fa9:8020/warehouse/tablespace/external/hive','hdfs://master-b882990:8020/warehouse/tablespace/external/hive');
进入新集群的 metastore 和 hiveserver 对应的服务器,以 root 身份执行以下命令。
systemctl start hive-metastore;
systemctl start hive-server2;
验证正常。