Hadoop

生产环境阿里 EMR(Hbase1.2+Phoenix4.10)夸集群数据迁移采坑实录

1. 生产场景

最近由于公司业务调整,新购了E-MapReduce集群,需将老E-MapReduce集群的数据迁移到新集群上(由于是iOT业务,又24小时实时写数据不中断)

  • Hbase(Phoenix)数据迁移方案主要分为:
  • Hadoop层面(distcp)
  • Hbase层面(copyTableexport/importsnapshot)

2. 以下针对 distcp 方案详细说明(以亲测阿里EMR为例)

2.1 首先打通两个集群网络(建议内网),新建一个tmp安全组,将两个集群的所有ECS都加入进来

2.2 Cluster-A中将HBase的表在HDFS存储文件distcp到Cluster-B的HBase在HDFS中对应的目录(一定要用hdfs账户)

[root@emr-header-1 ~]# sudo su hdfs
# 将表 safeclound.tb_ammeter 从A集群在线拷贝到B集群, 注: 老版本hdfs默认端口是9000新版本是8020
[hdfs@emr-header-1 ~]# hadoop distcp hdfs://ClusterA:8020/hbase/data/default/safeclound.tb_ammeter hdfs://ClusterB:8020/hbase/data/default

注: /hbase/data/defaultHbase 表在 Hdfs 存储路径,例如表sc.tb_test1的存储路径是/hbase/data/default/sc.tb_test1, 可以只有单个表的路径,也可以是default下面所有表的路径(即*表示),EMR的老版本 Hdfs 端口是 9000,新版hdfs端口是8020,这个具体情况而定就行。

特别注意: 千万不要把 HbasePhoenix 的系统表拷贝了,只需拷贝自建的业务表即可(因为distcp对于Cluster-B是覆盖操作),为了安全起见及亲测经验还是老老实实一张一张表拷贝吧,非常不建议使用 *,一是多个表数据量可能巨大,二是会把系统表拷贝过去了导致元数据出问题.

Cluster-B中执行HBase repair修复(一定要用hbase账户)

[root@emr-header-1 ~]# sudo su hbase
[hbase@emr-header-1 ~]# hbase hbck -repair # 执行hbase恢复命令, 让hbase引用distcp过来的hdfs表文件,重建 meta
[hbase@emr-header-1 ~]# hbase shell # 进入shell检查是否迁移成功
...
hbase(main):001:0> list # 列出当前所有表
hbase(main):001:0> scan 'safeclound.tb_ammeter', {LIMIT => 10} # 扫描表前10条数据

注: 根据亲测经验,如果执行 hbase hbck -repair 后在 hbase shell 中任然看不到迁移来的表,别急,先喝杯茶稍等一会儿(内网迁移通常 1~2 分钟内看数据量)然后再重新执行 hbase hbck -repair 命令,直到出现以下字幕,说明 Hbase 迁移就要成功了...

util.HBaseFsck: Sleeping 10000ms before re-checking after fix...

猜测此问题可能是由于hdfs拷贝过来后有些异步操作未完成所导致?

2.3 (若不是 Phoenix + Hbase 架构组合可忽略)

在上一步hbase shell检查迁移成功之后,再测试Phoenix查询,可能会出现在hbase shell中 list 或者 scan 命令都完全正常,但在Phoenix中看不到迁移过来的表,别急,因为 Phoenix 还不知道你从 hdfs 迁移的表,经过Google找到解决方法1:

  • 方案1: 通过在 Phoenix 执行 create view ... 语句,创建一个视图就可以了(但后续还要维护视图,如果不像创建view 可参考以下2方案)
  • 方案2: 直接在 Phoenix 执行 create table ... 语句,(警告: 如果集群数据量过大,此方式可能会出现 Huang 住最后导致 Hbase 某个节点宕机, 亲身经历, 非万不得已不推荐使用!)
  • 方案3: 但也不是没有 "优雅" 的办法, 防止方案2宕机, 亲测还有一个巧妙的 "玄学" 办法: 在执行 create table 时无需等待执行完成,当按下Enter键执行后, 过1秒后立即 Ctrl+C 终止 sqlline.py 进程, 然后重新打开 sqlline.py, 执行 !table 命令就可以看到新迁移的表了 (警告: 非万不得已不推荐使用!)

2. FAQ

2.1. 不小心误覆盖了 ClusterB 的系统表如何恢复?

  • step1) 首先备份 Hbase 在 Hdfs 上的根目录
[root@emr-header-1 ~]# hdfs dfs -mv /hbase /hbase_bak
  • step2) 停掉 Hbase 所有服务(若 EMR 新版,可在阿里 EMR 控制台 Stop Hbase ALL
  • step3) 清除 ZK 里 Hbase 的注册信息(很关键,否则不会自动生成系统表)
[root@emr-header-1 ~]# ./zkCli.sh -server localhost:2181
[zk: localhost:2181(CONNECTED) 1] ls /
[zk: localhost:2181(CONNECTED) 1] rmr /hbase
  • step4) 重新启动hbase所有服务
  • step5) 测试hbase是否自动生成
[root@emr-header-1 ~]# hdfs dfs -ls / # 查看hdfs里是否重新生成了/hbase目录
[root@emr-header-1 ~]# hbase shell
hbase(main):001:0> list # 再查看 hbase 里是否可见相应的系统表

TABLE
SYSTEM.CATALOG
SYSTEM.FUNCTION
SYSTEM.MUTEX
SYSTEM.SEQUENCE
SYSTEM.STATS
5 row(s) in 0.1010 seconds
...

恭喜,出现以上字幕即恢复成功!

2.2. 如何使用离线拷贝 ?

  • step1) 只需将 distcp 命令改用 getput 通过本地中转就行了(无关心执行账户)
#从源hbase集群下载业务表到本地
[root@emr-header-1 ~]$ hdfs dfs -get /hbase/data/default/safeclound.tb_ammeter_analyze
  • step2) scp 到目地 Hbase 集群服务器
[root@emr-header-1 ~]$ tar -cvf safeclound.tb_ammeter_analyze.tar safeclound.tb_ammeter_analyze
[root@emr-header-1 ~]$ scp safeclound.tb_ammeter_analyze.tar root@emr-header-1:/root
  • step3) 在目地服务器上将业务表文件加载到 Hdfs(其中emr-header-1安装的是原生Hbase且是默认配置,因此在Hdfs的数据文件路径才是: /tmp/hbase-root/hbase/data/default/

,如果是阿里云的EMR,则在hdfs的数据路径为:/hbase/data/default)

[root@emr-header-1 ~]# hdfs dfs -put /root/safeclound.tb_ammeter_analyze/ /tmp/hbase-root/hbase/data/default/
  • step4) 查看验证是否加载成功
[root@emr-header-1 ~]# hadoop fs -ls /tmp/hbase-root/hbase/data/default/
  • step5) 接下来在新集群 ClusterB 中执行 hbase hbck -repair 修复命令, 操作过程同上...

2.3 若使用的是 Phoenix+Hbase 组合,若 Phoenix4.7 升级到 4.10之后,可能会出现除主键字段外其他字段都查不出数据,但在 hbase shellscan 表又有数据, 这种情况如何处理?

参考 Phoenix 官网资料: http://phoenix.apache.org/columnencoding.html

phoenix官网截图

其他参考文献

留言

您的电子邮箱地址不会被公开。