CDH开启HBase Replication

一、环境准备

1、要求两套集群安装相同的CDH版本,如都为CDH4或者CDH5,不限定小版本
2、要求两套集群网络互通,至少保证Master HBase到Salve HBase网络是可达的

二、开启HBase replication功能

启用HBase复制功能,如下图:
《CDH开启HBase Replication》 image.png

在修改配置后, 需要重启HBase集群,建议采用滚动重启的方式重启HBase各个实例。

三、配置hosts

在Master集群所有机器的hosts中配置Slave集群的hostname与ip
需要注意的地方有:
1、至少配置slave集群的HBase和zk的hostname
2、hostname必须与slave集群内部使用的hostname一致

四、增加peer

在建立peer前,首先简单的介绍下hbase关于peer的原理以及操作命令,建议参照hbase复制详解。上文介绍得非常的详细,在这里不累述,主要介绍如何正确的关闭一个peer。
首先回顾下创建一个peer的过程:

  • 新增一个peer
add_peer 'peerID','zkIp:2181:/hbase'

其中peerID不可与已经存在的peer冲突,可通过list_peers查看已有的peer;
如果配置多个zk:zk1,zk2:2181:/hbase

  • 将peerID=1的peer应用表t1
    对于已经建立的表,需要开启REPLICATION_SCOPE属性,如:
disable 't1'
alter 't1',{NAME=>"cf", REPLICATION_SCOPE=>"1"}
enable 't1'

对于REPLICATION_SCOPE属性,一开始我一度以为其值=peerID,并且在设置时并未报错。经过查看源码,发现REPLICATION_SCOPE的取值范围为(0,1,2),源码在HConstants类中定义了三种模式:

/**
   * 本地模式,当前数据不会被复制
   * Scope tag for locally scoped data.
   * This data will not be replicated.
   */
  public static final int REPLICATION_SCOPE_LOCAL = 0;

  /**
   * 全局模式,此数据会被复制给所有peer
   * Scope tag for globally scoped data.
   * This data will be replicated to all peers.
   */
  public static final int REPLICATION_SCOPE_GLOBAL = 1;

  /**
   * 连续模式,数据会按照队列ID的顺序复制给所有的peer
   * Scope tag for serially scoped data
   * This data will be replicated to all peers by the order of sequence id.
   */
  public static final int REPLICATION_SCOPE_SERIAL = 2;

对于0和1这两个取值还比较好理解,而2并不能简单的从上面得到解释

在hbase-default.xml中找到如下解释:
《CDH开启HBase Replication》 image.png 目前来看serially模式,大概为按照Master集群的HLog写入顺序在Slave集群实现同样的顺序,当前这会增加集群的延时,同时需要将hbase.assignment.usezk 和 hbase.master.distributed.log.replay两项配置设置为false才能启用。

  • 将peer应用到表
set_peer_tableCFs 'peerId,'table:cf;table1:cf1,cf2'
append_peer_tableCFs 'peerId,'table:cf;table1:cf1,cf2'

许多的博文里都有提到这两个命令,但是却没有指出两者的区别,这阅读源码(HBase1.2)后,得到这样的解释:

1、append_peer_tableCFs

增加peer到表,粒度到列簇。

2、set_peer_tableCFs

更新tableCFs到peer。假如事先执行了append_peer_tableCFs ‘peerId,’table:cf;table1:cf1,cf2’,再执行set_peer_tableCFs ‘peerId’,’table1:cf1’,那么table1:cf2将从当前peer中移除,而append_peer_tableCFs会保留已有的列簇。两个方式实现的源码如下:

public static UpdateReplicationPeerConfigRequest buildUpdateReplicationPeerConfigRequest(
      String peerId, ReplicationPeerConfig peerConfig) {
    UpdateReplicationPeerConfigRequest.Builder builder = UpdateReplicationPeerConfigRequest
        .newBuilder();
    builder.setPeerId(peerId);
    builder.setPeerConfig(ReplicationSerDeHelper.convert(peerConfig));
    return builder.build();
  }
public static void appendTableCFsToReplicationPeerConfig(
      Map<TableName, ? extends Collection<String>> tableCfs, ReplicationPeerConfig peerConfig) {
    Map<TableName, List<String>> preTableCfs = peerConfig.getTableCFsMap();
    if (preTableCfs == null) {
      peerConfig.setTableCFsMap(tableCfs);
    } else {
      for (Map.Entry<TableName, ? extends Collection<String>> entry : tableCfs.entrySet()) {
        TableName table = entry.getKey();
        Collection<String> appendCfs = entry.getValue();
        if (preTableCfs.containsKey(table)) {
          List<String> cfs = preTableCfs.get(table);
          if (cfs == null || appendCfs == null || appendCfs.isEmpty()) {
            preTableCfs.put(table, null);
          } else {
            Set<String> cfSet = new HashSet<String>(cfs);
            cfSet.addAll(appendCfs);
            preTableCfs.put(table, Lists.newArrayList(cfSet));
          }
        } else {
          if (appendCfs == null || appendCfs.isEmpty()) {
            preTableCfs.put(table, null);
          } else {
            preTableCfs.put(table, Lists.newArrayList(appendCfs));
          }
        }
      }
    }
  }

至此,可以验证在Master集群中往表t1写入数据,观察Slave集群是否成功备份。

上面介绍了开启一个表的复制,需要开启REPLICATION_SCOPE属性,然后应用某一个peer,是否会存在这TABLE_CFS和REPLICATION_SCOPE配置有什么区别的疑问?
REPLICATION_SCOPE 是让 replicationSource 开启的 WAL reader 能够看到 log 里哪些 WALEntry 能被 replication , TABLE_CFS 则是在 WALEntry 中过滤出真正需要复制的 cf 数据

五、删除peer

一开始以为删除一个peer的方式很简单,只需运行命令

remove_peer 'peerId'

但是,观察到regionServer日志依旧在尝试连接Slave集群,并且在Master集群的t1表写入数据后,Slave集群依旧同步到了。
《CDH开启HBase Replication》 image.png

显示,这样并没有成功的删除表的复制链路。如下图:
《CDH开启HBase Replication》 image.png 在zk的/hbase/replication/peers/下只有一个peer,但是在rs/region的config里还存在被remove后的peer。一开始我采用在zk里删除rs/region下错误的peer的方式,但是不久后又被创建,猜测这份配置已经被hbase加载到了内存中。

一种解决方式为:在remove peer后,将table的REPLICATION_SCOPE属性修改为0。当然,在生产环境对表进行disable也是非常不可取的。

另外一种解决方式:先remove_peer_tableCFs删除表对应的peer信息,再删除peer,一定要记住顺序。最后将表的REPLICATION_SCOPE修改为。修改

我目前并没有测试成功,但是查看社区是有人这么完成了的。就是使用enable_table_replication命令。

《CDH开启HBase Replication》 image.png

    原文作者:凡尔Issac
    原文地址: https://www.jianshu.com/p/842f28a55ba1
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞