HBase默认采用异步复制的方式同步数据,即客户端执行完put之后,RegionServer的后台线程不断地推送HLog的Entry到Peer集群。这种方式一般能满足大多数场景的需求,例如跨集群数据备份、HBase集群间数据迁移等。但是HBase 1.x版本的复制功能,无法保证Region迁移前后的HLog的Entry按照严格一致的顺序推送到备集群,某些极端情况下可能造成主从集群数据不一致。为此,社区在HBase 2.x版本上实现了串行复制来解决这个问题。
另外,默认的异步复制无法满足强一致性的跨机房热备需求。因为备份机房的数据肯定会落后主集群,一旦主集群异常,无法直接切换到备份集群,因此,社区提出并研发了同步复制。
一、复制场景及原理
1,场景
现在有一个SSD的HBase集群被业务方A访问,业务方A对HBase集群的延迟和可用性要求非常高。现在又收到业务方B的需求,希望对表TableX跑数据分析任务(用MapReduce或者Spark来实现)。对HBase来说,这种任务都是用大量的scan去扫全表来实现的。如果直接去扫SSD在线集群,会极大影响集群的延迟和可用性,对业务方A来说不可接受。另外,业务方B的数据分析任务是一个每天定期跑的任务,希望每次分析的数据都尽可能是最新的数据。
如何解决这个问题?,思路是用一批成本较低的HDD机器搭建一个离线的HBase集群,然后把表TableX的全量数据导入离线集群,再通过复制把增量数据实时地同步到离线集群,业务方B的分析任务直接跑在离线集群上。这样既满足了业务方B的需求,又不会对业务方A造成任何影响。
操作步骤:
(1)先确认表TableX的多个Column Family都已经将REPLICATION_SCOPE设为1。
(2)在SSD集群上添加一条DISABLED复制链路,提前把主集群正在写入的HLog堵在复制队列中。
add_peer '100', CLUSTER_KEY => "zk1,zk2,zk3:11000:/hbase-hdd", STATE => "DISABLED",
TABLE_CFS => {
"TableX" => []
(3)对TableX做一个Snapshot,并用HBase内置的ExportSnapshot工具把Snapshot拷贝到离线集群上。注意,不要使用distcp拷贝snapshot,因为容易在某些情况下造成数据丢失。
(4)待Snapshot数据拷贝完成后,从Snapshot中恢复一个TableX表到离线集群。
(5)打开步骤1中添加的Peer:
enable_peer '100'
(6)等待peer=100,所有堵住的HLog都被在线集群推送到离线集群,也就是两个集群的复制延迟等于0,就可以开始在离线集群上跑分析任务了。
注意:为什么需要在步骤2创建一个DISABLED的Peer?
因为步骤3要完成Snapshot到离线集群的拷贝,可能需要花费较长时间。业务方A在此期间会不断写入新数据到TableX,如果不执行步骤2,则会造成离线集群丢失在拷贝Snapshot过程中产生的增量数据,造成主备集群数据不一致。提前创建一个DISABLED的Peer,可以使拷贝Snapshot过程中产生的增量数据都能堆积在Peer的复制队列中,直到拷贝Snapshot完成并enable_peer之后,由在线集群的RegionServer把这一段堵在复制队列中的HLog慢慢推送到离线集群。这样就能保证在线集群和离线集群数据的最终一致性。
2,管理流程的设计和问题
复制功能在HBase 1.x版本上实现的较为粗糙。Peer是指一条从主集群到备份集群的复制链路。一般在创建Peer时,需要指定PeerId、备份集群的ZooKeeper地址、是否开启数据同步ÿ