持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
需求:
hive集群之间相互迁移数据,生产A集群迁移到B集群等场景,需要做表结构的迁移和数据的迁移
表结构迁移
说明,数据迁移之前必须要先建表,可以利用hive免交互参数-e -f等来 导出导入表结构
表结构导出
使用hive自带的命令操作
#免交互式将 表结构导出到文本文件中 文件后缀可变
hive -e "use dws;show create table dws_a_n_word;" > dws_a_n_word.hql
表结构导入
使用hive自带的命令操作
#导入前,需要先切换库名称,默认创建在default库中,使用sed命令 及1i参数在第一行插入
sed -i "1iuse dws;" dws_a_n_word.hql
#执行sql,创建表及结构
hive -f dws_a_n_word.hql
表数据迁移
方式一,导入导出方式
导出数据
#下载到当前目录, 点(.) 表示当前目录
hadoop fs -get /user/hive/warehouse/dws.db/dws_a_n_word .
#将目录打成压缩包
tar zcf dws_a_n_word.tar.gz dws_a_n_word
导入数据
将压缩包 上传到目标服务器后
#解压
tar xf dws_a_n_word.tar.gz
#上传 put参数会自动识别目录和文件
hadoop fs -put dws_a_n_word /user/hive/warehouse/dws.db/
方式二,distcp迁移
使用hadoop自带的distcp 跨集群或集群内实现迁移,因为distcp最终是提交的MR任务,所以速度上会比较慢
#源需要写表的完整路径, 目标只需要写库的路径,会迁移到库目录下
hadoop distcp hdfs://ip:port/user/hive/warehouse/dws.db/dws_a_n_word hdfs://ip:port/user/hive/warehouse/dws.db/
数据验证
手动执行sql语句比对和抽样查看
use dws;
#会提交到yarn
select count(*) from dws_a_n_word;
#直接查询结果
select * from dws_a_n_word limit 50;
如果是分区表,且查不到数据,执行下列命令修复
MSCK REPAIR TABLE xxx;
单分区双分区表测试直接修复没问题
当多于双分区后,例如三个分区partation (xx,xxx,xxx)
修复依然无用
就需要加上以下配置再修复:
set hive.msck.path.validation=ignore
msck repair table 表名
自动化脚本
单个或者几个表的迁移,手动执行一下关系也不大,一旦这是经常性的工作,或者需要迁移大量的表,就不得不需要自动化来提交效率了
请不要直接在生效环境执行下列脚本,尽量在测试环境验证
该脚本需要在拥有hive和hadoop命令权限的机器才能运行 该脚本是全量从A集群迁移表结构和数据到B集群 该脚本有2处todo需自行操作
#!/bin/bash
#导出dws库所有表名
hive -e "use dws;show tables;" > tables.txt
#声明数组
tables=$(cat tables.txt)
#指定库名
echo "use dws;" >> hive_dws_migration.hql
#循环导出表结构和表数据
for i in ${tables[@]}
do
echo $i
hive -e "use dws;show create ${i};" > hive_dws_migration.hql
hadoop fs -get /user/hive/warehouse/dws.db/${i} /opt/hive_migration/
done
#上传表结构和表数据到目标服务器
#根据自身环境而定,scp ftp sync等方式
#todo
#登陆目录服务器
#todo
#导入表结构
hive -f hive_dws_migration.hql
#导入数据
for i in ${tables[@]}
do
echo $i
hadoop fs -put hive_migration/${i} /user/hive/warehouse/dws.db/
done
#数据校验根据自身规则执行
#例子验证某表中 其中一段时间的数据,验证多张表,请使用for循环
#例子表
table=dws_a_n_word
#例子统计
count=$(hive -e "select count(*) from dws.${table}
where create_time >= unix_timestamp(date_add('2022-03-27', -1), 'yyyy-MM-dd')
and create_time < unix_timestamp('2022-03-27', 'yyyy-MM-dd');")
#例子判断
if [ $count -lt 100000 ];
echo "错误: 数据量不匹配,低于1万条"
fi