机房迁移等工作有大量的数据迁移工作,DistCp是HDFS数据迁移的标准工具,很多人都有实践过。而ES和HBase的迁移比较少有人提及,这篇文章就包含了我的一点经验,希望能帮助你。

ES数据

ES有snapshot功能,将index中的数据存到静态文件中,或者从静态文件中还原。老机房和新机房各有一个分布式的mfs,在老机房中把snapshot写到mfs里,用rsync拷贝到新机房中,然后再还原到新机房的ES里,就可以实现数据迁移。

准备共享存储和Repository

所有的ES服务都会将文件写到相同的本地目录中,一般把共享存储挂载到每一台机器的相同路径下。共享存储最好大一些,本文中使用MooseFS。值得注意的是,由于安全考虑,新版的ElasticSearch对repository的路径进行了限制,只能在参数文件中path.repo的配置里选择。

kopf的页面里,进入repository页面(或者snapshot页面,根据kopf的版本而不同),根据提示创建repository。在下面的例子中,我们使用mfs作为刚创建的repository的名字。

制作snapshot

打开旧机房ES的kopf页面,进入repository页面,点击“Create snapshot”,输入snapshot的名字,repository选择mfs,indices中选择需要备份的index名。

注意:在我们的机房中ES机器上的用户名ID不一致,导致挂载上去的mfs在不同机器上看到的权限不同,创建snapshot后能看到结果是“Partial”,看log会发现某些机器无法写到mfs目录。我的做法是,在正式创建snapshot之前,需要手动修改权限。具体如下:假设index名称是A,有5个shards。进入/mfs/es_snapshots/indices/,创建目录A,在目录A中创建子目录0到4,然后把A目录和下面的子目录的权限都改为777。这个时候再创建这个index的snapshot。

数据拷贝

在新机房的ES的机器(c1-es1)上,切换到用户es,执行如下命令:

rsync --update -avP -e 'ssh -p ssh_port' es@from_es_ip:/mfs/es_snapshots/ /mfs/es_snapshots/

对于很大的index,可以用nohup放到后台跑。

数据还原

进入新机房ES的kopf页面,进入snapshot,在repository中选择mfs,下面展开的snapshot中应该有刚拷贝过来的备份。点击restore,在rename中对index重新命名,具体方法参见文档

restore后,新的index会默认拥有所有之前的settings。如果以前的index有tag,而新机房中的机器没有tag标签,那么需要将这个tag去掉才能初始化。

等一个snapshot还原后,再进行下一个。

Hbase数据

常用的HBase数据迁移,会用到hbase replication。但这次我们是一次性的数据迁移,并且老机房的hbase机器并没有开启replication,启用需要重启所有的server,代价比较大。所以这里我使用了比较简便的CopyTable的方法。

准备工作

我们的Hbase集群使用了自定义的安全机制,由于CopyTable是从源cluster主动推向目标cluster,所有需要让源cluster能连接到目标集群,同时让目标cluster添加源cluster的所有机器。 如果有任何一个机器没有正确配置,都可能导致copy过程失败。在开始前最好用工具来检查所有机器的连通性。

另外,CopyTable不会在目标集群中自动创建新的table,需要手动在新机房的Hbase中创建目标table,并要求有相同的column family。

命令

在老机房执行命令:

hbase org.apache.hadoop.hbase.mapreduce.CopyTable \
  --new.name=yisou:btype \
  --peer.adr=c1-hd-nn1.bdp.idc,c1-hd-nn2.bdp.idc,c1-hd-nn3.bdp.idc:2181:/hbase \
  btype

参见文档 , 随后检查一下行数对不对。 还可以根据时间等进行部分的增量拷贝,具体参看文档。