背景
存在某种情况,HIVE数据可能要从一个HDFS中,传到另一个hdfs中。可以说是迁移,也可能是数据同步。
过程
假设有一张user表如下:
CREATE TABLE `jc_db.t_user` (
`id` bigint COMMENT '主键',
`username` string COMMENT '账号',
`password` string COMMENT '密码',
`create_time` string COMMENT '创建时间'
)
PARTITIONED BY (
`c_date` string)
STORED AS ORC;
c_date字段是年月日yyyyMMdd,也就是按天分区。
1.在旧的HDFS的集群中的hive里执行命令,将hive数据导出到一个HDFS目录下
export table jc_db.t_user to '/tmp/hive-export/jc_db_t_user';
以上默认是将jc_db.t_user所有数据都会导出到HDFS目录/tmp/hive-export/jc_db_t_user
2.用DistCp将刚刚的HDFS目录/tmp/hive-export/jc_db_t_user 复制进新的HDFS,在新的HDFS集群执行以下命令:
hadoop distcp -D ipc.client.fallback-to-simple-auth-allowed=true -D dfs.checksum.type=CRC32 hdfs://旧的namenode ip:9000/tmp/hive-export/jc_db_t_user /tmp/hive-export/jc_db_t_user
3.在新的HDFS恢复数据到hive中
import table jc_db.t_user from '/tmp/hive-export/jc_db.t_user';
4.数据每天都会产生,所以没必要数据两个HDFS集群都从mysql中获取,而且mysql是单点,存在性能和带宽问题,所以我们按分区,每天的同步过去,此时:
4.1 在旧的HDFS的集群中的hive里执行命令,将hive数据导出到一个HDFS目录下,但是要c_date分区:
export table jc_db.t_user partition(l_date=20180826) to '/tmp/hive-export/jc_db_t_user_20180826';
4.2 用DistCp将刚刚的HDFS目录/tmp/hive-export/jc_db_t_user_20180826 复制进新的HDFS,在新的HDFS集群执行以下命令:
hadoop distcp -D ipc.client.fallback-to-simple-auth-allowed=true -D dfs.checksum.type=CRC32 hdfs://旧的namenode ip:9000/tmp/hive-export/jc_db_t_user_20180826 /tmp/hive-export/jc_db_t_user_20180826
4.3 在新的HDFS恢复分区数据到hive中,并不会影响历史数据。
import table jc_db.t_user from '/tmp/hive-export/jc_db_t_user_20180826';
TroubleShoot
Failed with exception Cannot get DistCp constructor: org.apache.hadoop.tools.DistCp.<init>()
下载DistCp依赖放入hive的lib目录
wget http://central.maven.org/maven2/org/apache/hadoop/hadoop-distcp/2.6.5/hadoop-distcp-2.6.5.jar