1

背景

存在某种情况,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

电脑杂技集团
208 声望32 粉丝

这家伙好像很懂计算机~