生产环境阿里 EMR(Hbase1.2+Phoenix4.10)夸集群数据迁移采坑实录
1. 生产场景
最近由于公司业务调整,新购了E-MapReduce集群,需将老E-MapReduce集群的数据迁移到新集群上(由于是iOT业务,又24小时实时写数据不中断)
- Hbase(Phoenix)数据迁移方案主要分为:
- Hadoop层面(
distcp
) - Hbase层面(
copyTable
、export/import
、snapshot
)
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/default
是Hbase
表在Hdfs
存储路径,例如表sc.tb_test1
的存储路径是/hbase/data/default/sc.tb_test1
, 可以只有单个表的路径,也可以是default下面所有表的路径(即*表示),EMR的老版本Hdfs
端口是9000
,新版hdfs
端口是8020
,这个具体情况而定就行。特别注意: 千万不要把
Hbase
和Phoenix
的系统表拷贝了,只需拷贝自建的业务表即可(因为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
命令改用get
、put
通过本地中转就行了(无关心执行账户)
#从源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
组合,若 Phoenix
从 4.7
升级到 4.10
之后,可能会出现除主键字段外其他字段都查不出数据,但在 hbase shell
中 scan
表又有数据, 这种情况如何处理?
参考 Phoenix 官网资料: http://phoenix.apache.org/columnencoding.html