
# 配置HBase主备集群容灾
#### 操作场景
HBase集群容灾作为提高HBase集群系统高可用性的一个关键特性，为HBase提供了实时的异地数据容灾功能。对外提供了基础的运维工具，包含灾备关系维护、重建、数据校验、查看数据同步进展等功能。为了实现数据的实时容灾，可以把本HBase集群中的数据备份到另一个集群，支持HBase表普通写数据与Bulkload批量写数据场景下的容灾。
#### 前提条件
- 主备集群都已经安装并启动成功，且获取集群的管理员权限。

- 必须保证主备集群间的网络畅通和端口的使用。
- 如果主集群部署为安全模式且不由一个FusionInsight Manager管理，主备集群必须已配置跨集群互信。如果主集群部署为普通模式，不需要配置跨集群互信。
- 主备集群必须已配置跨集群拷贝功能。
- 主备集群上的时间必须一致，而且主备集群上的NTP服务必须使用同一个时间源。
- 必须在主备集群的所有节点的hosts文件中，配置主备集群所有机器的机器名与业务IP地址的对应关系。 如果主集群的客户端安装在集群外的节点上，也需在该节点的hosts文件中配置主备集群所有机器的机器名与业务IP地址的对应关系。
  
- 主备集群间的网络带宽需要根据业务流量而定，不应少于最大的可能业务流量。
- 主备集群安装的MRS版本需要保持一致。
- 备集群规模不小于主集群规模。
 
#### 约束与限制
- 尽管容灾提供了实时的数据复制功能，但实际的数据同步进展是由多方面的因素决定的，例如，当前主集群业务的繁忙程度，备集群进程的健康状态等。因此，在正常情况下，备集群不应该接管业务。极端情况下是否可以接管业务，可由系统维护人员以及决策人员根据当前的数据同步指标来决定。

- 容灾功能当前仅支持一主一备。
- 通常情况下，不允许对备集群的灾备表进行表级别的操作，例如修改表属性、删除表等，一旦误操作备集群后会造成主集群数据同步失败、备集群对应表的数据丢失。
- 主集群的HBase表已启用容灾功能同步数据，用户每次修改表的结构时，需要手动修改备集群的灾备表结构，保持与主集群表结构一致。
 
#### 操作步骤
**配置主集群普通写数据容灾参数。**
1. 登录主集群的Manager。 
   登录集群Manager具体操作，请参考[访问MRS集群Manager](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0128.html)。
   
   
2. 选择"集群 \> 服务 \> HBase \> 配置"，单击"全部配置"，进入HBase配置界面。 
   ![](https://support.huaweicloud.com/cmpntguide-lts-mrs/zh-cn_image_0000001676748298.png "点击放大")
   
   
3. （可选）如[表1]所示，为HBase容灾操作过程中的可选配置项，您可以根据描述来进行参数配置，或者使用缺省提供的值。
   
    表1容灾可选配置项 
   | 配置入口                          | 配置项                                          | 缺省值      | 描述                                                                                                                                |
   |:---|:---|:---|:---|
   | "HMaster \> 性能"               | hbase.master.logcleaner.ttl                  | 600000   | 指定HLog的保存期限。如果配置值为"604800000"（单位：毫秒），表示HLog的保存期限为7天。                                                                              |
   | "HMaster \> 性能"               | hbase.master.cleaner.interval                | 60000    | HMaster清理过去HLog文件的周期，即超过设置的时间的HLog会被自动删除。建议尽可能配置大的值来保留更多的HLog。                                                                    |
   | "RegionServer \> Replication" | replication.source.size.capacity             | 16777216 | edits最大大小，单位为byte。如果edit大小超过该值，HLog edits将会发送到备集群。                                                                                |
   | "RegionServer \> Replication" | replication.source.nb.capacity               | 25000    | edits最大数目，这是另一个触发HLog edits到备集群的条件。当主集群同步数据到备集群中时，主集群会从HLog中读取数据，此时会根据本参数配置的个数读取并发送。该参数与"replication.source.size.capacity"一起配置使用。 |
   | "RegionServer \> Replication" | replication.source.maxretriesmultiplier      | 10       | Replication出现异常时的最大重试次数。                                                                                                          |
   | "RegionServer \> Replication" | replication.source.sleepforretries           | 1000     | 每次重试的sleep时间（单位：毫秒）。                                                                                                              |
   | "RegionServer \> Replication" | hbase.regionserver.replication.handler.count | 6        | RegionServer上的Replication RPC服务器实例数。                                                                                              |
      
   
   
**配置主集群Bulkload批量写数据容灾参数。**
4. 是否启用Bulkload批量写数据容灾功能？ 
   是，执行[5]。
   否，执行[8]。
   
   
5. 选择"集群 \> 服务 \> HBase \> 配置"，单击"全部配置"，进入HBase配置界面。
6. 搜索并修改"hbase.replication.bulkload.enabled"参数，将配置项的值修改为"true"，启用Bulkload批量写数据容灾功能。
7. 搜索并修改"hbase.replication.cluster.id"参数，表示标识主集群HBase的ID，用于备集群连接主集群。参数值支持大小写字母、数字和下划线（_），长度不超过30。
**重启HBase服务并安装客户端。**
8. 单击"保存"，保存配置。单击"概览"，选择"更多 \> 重启服务"，输入当前用户密码，单击"确定"重启HBase服务。
9. 在主备集群，选择"集群 \> 服务 \> HBase \> 更多 \> 下载客户端"，下载并安装客户端并，具体操作请参考[安装客户端](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0089.html)章节。
**添加主备集群容灾关系。**
10. 以客户端安装用户登录安装了主集群客户端的节点，并使用"hbase"用户登录**hb** **ase shell** 界面。
    
    1. 切换至客户端安装目录：
       ```
       cd 客户端安装目录
       ```
       
    
    2. 配置环境变量：
       ```
       source bigdata_env
       ```
       
    
    3. 认证用户，集群未启用Kerberos认证（普通模式）请跳过该操作：
       ```
       kinit hbase
       ```
       
    
    4. 登录HBase客户端：
       ```
       hbase shell
       ```
       
    
    
    
    
11. 在**hb** **ase shell** 中执行如下命令，创建主集群HBase与备集群HBase之间的容灾同步关系。
    
    ```
    add_peer '备集群ID', CLUSTER_KEY => "备集群ZooKeeper业务IP地址", CONFIG => {"hbase.regionserver.kerberos.principal" => "备集群RegionServer principal", "hbase.master.kerberos.principal" => "备集群HMaster principal"}
    ```
    - 备集群ID表示主集群识别备集群使用的ID，请重新指定ID值。可以任意指定，建议使用数字。
    
    - 备集群ZooKeeper地址信息包含ZooKeeper实例业务IP地址、客户端连接服务器的端口和备集群的HBase在ZooKeeper上的根目录。
      - 备集群ZooKeeper实例业务IP地址可在FusionInsight Manager界面，选择"集群 \> 服务 \> ZooKeeper \> 实例"查看。
      
      - 备集群ZooKeeper客户端连接服务器的端口和备集群的HBase在ZooKeeper上的根目录，可在FusionInsight Manager界面，选择"集群 \> 服务 \> ZooKeeper \> 配置"，分别搜索"clientPort"和"zookeeper.znode.parent"参数获取。
       
    
    - **hbase.master.kerberos.principal** 、**hbase.regionserver.kerberos.principal** 在备集群的"*客户端安装目录*/HBase/hbase/conf/hbase-site.xml" 配置文件中查找。
    
    
    例如，执行以下命令添加主备集群容灾关系：
    ```
    add_peer '备集群ID', CLUSTER_KEY => "192.168.40.2,192.168.40.3,192.168.40.4:24002:/hbase", CONFIG => {"hbase.regionserver.kerberos.principal" => "hbase/hadoop.hadoop.com@HADOOP.COMhbase/hadoop.hadoop.com@HADOOP.COM", "hbase.master.kerberos.principal" => "hbase/hadoop.hadoop.com@HADOOP.COM"}
    ```
    
    
12. （可选）如果启用BulkLoad批量写数据容灾功能，主集群HBase客户端配置必须复制到备集群。 
    1. 在备集群HDFS中创建目录"/hbase/replicationConf/*主集群hbase.replication.cluster.id*"。
    
    2. 将主集群HBase客户端配置文件复制到备集群创建的HDFS目录"/hbase/replicationConf/*主集群hbase.replication.cluster.id* "中，例如，命令如下：
       ```
       hdfs dfs -put HBase/hbase/conf/core-site.xml HBase/hbase/conf/hdfs-site.xml HBase/hbase/conf/yarn-site.xml hdfs://NameNode IP:25000/hbase/replicationConf/source_cluster
       ```
       
    
    
    
    
**启用HBase容灾功能同步数据。**
13. 检查备集群的HBase服务实例中，是否已存在一个命名空间，与待启用容灾功能的HBase表所属的命名空间名称相同？ 
    - 是，存在同名的命名空间，执行[14]。
    
    - 否，不存在同名的命名空间，需先在备集群的**hbase shell** 中创建同名的命名空间，然后执行[14]。
    
    
    
    
14. 在主集群的**hb** **ase shell** 中，以"hbase"用户执行以下命令，启用将主集群表的数据实时容灾功能，确保后续主集群中修改的数据能够实时同步到备集群中。一次只能针对一个HTable进行数据同步。
    
    ```
    enable_table_replication '表名'
    ```
    需注意：
    - 如果备集群中不存在与要开启实时同步的表同名的表，则该表会自动创建。
    
    - 如果备集群中存在与要开启实时同步的表同名的表，则两个表的结构必须一致。
    
    - 如果**'** *表名* **'**设置了加密算法SM4（也称为SMS4）或AES，则不支持对此HBase表启用将数据从主集群实时同步到备集群的功能。
    
    - 如果备集群不在线，或备集群中已存在同名但结构不同的表，启用容灾功能将失败。
    
    - 如果主集群中部分Phoenix表启用容灾功能同步数据，则备集群中不能存在与主集群Phoenix表同名的普通HBase表，否则启用容灾功能失败或影响备集群的同名表正常使用。
    
    - 如果主集群中Phoenix表启用容灾功能同步数据，还需要对Phoenix表的元数据表启用容灾功能同步数据。需配置的元数据表包含SYSTEM.CATALOG、SYSTEM.FUNCTION、SYSTEM.SEQUENCE和SYSTEM.STATS。
    
    - 如果主集群的HBase表启用容灾功能同步数据，用户每次为HBase表增加新的索引，需要手动在备集群的灾备表增加二级索引，保持与主集群二级索引结构一致。
    
    
    
    
15. （可选）如果HBase没有使用Ranger，在主集群的**hb** **ase shell** 中，以"hbase"用户执行以下命令，启用主集群的HBase表权限控制信息数据实时容灾功能。
    
    ```
    enable_table_replication 'hbase:acl'
    ```
    
    
**创建用户**。
16. 登录备集群的FusionInsight Manager，选择"系统 \> 权限 \> 角色 \> 添加角色"创建一个角色，并根据主集群HBase源数据表的权限，为角色添加备集群数据表的相同权限。
17. 选择"系统 \> 权限 \> 用户 \> 添加用户"创建一个用户，根据业务需要选择用户类型为"人机"或"机机"，并将用户加入创建的角色。使用新创建的用户，访问备集群的HBase容灾数据。 
    需注意：
    - 主集群HBase源数据表修改权限时，如果备集群需要正常读取数据，请修改备集群角色的权限。
    
    - 如果当前组件使用了Ranger进行权限控制，须基于Ranger配置相关策略进行权限管理，具体操作可参考[添加HBase的Ranger访问权限策略](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_1857.html)。
    
    
    
    
**同步主集群表数据。**
18. 检查配置HBase容灾并启用数据同步后，主集群是否已存在表及数据，且历史数据是否需要同步到备集群？ 
    - 是，存在表且需要同步数据，以HBase表用户登录安装主集群HBase客户端的节点，并执行以下命令认证身份。该用户需要拥有表的读写权限，以及"hbase:meta"表的执行权限。然后执行[19]。
      ```
      kinit 用户名
      ```
      
    
    - 否，不需要同步数据，任务结束。
    
    
    
    
19. 配置HBase容灾时不支持自动同步表中的历史数据，需要对主集群的历史数据进行备份，然后再手动恢复历史数据到备集群中。手动恢复即单表的恢复，单表手动恢复通过Export、distcp、Import来完成。
    
    单表手动恢复操作步骤：
    1. 从主集群导出表中数据。
       ```
       hbase org.apache.hadoop.hbase.mapreduce.Export -Dhbase.mapreduce.include.deleted.rows=true表名 保存源数据的目录
       ```
       例如：
       ```
       hbase org.apache.hadoop.hbase.mapreduce.Export -Dhbase.mapreduce.include.deleted.rows=true t1 /user/hbase/t1
       ```
       
    
    2. 把导出的数据复制到备集群。
       ```
       hadoop distcp 主集群保存源数据的目录 hdfs://ActiveNameNodeIP:8020/备集群保存源数据的目录
       ```
       其中，ActiveNameNodeIP是备集群中主NameNode节点的IP地址。
       例如：
       ```
       hadoop distcp /user/hbase/t1 hdfs://192.168.40.2:8020/user/hbase/t1
       ```
       
    
    3. 使用备集群HBase表用户，在备集群中导入数据。
       1. 在备集群HBase shell界面，使用"hbase"用户执行以下命令保持写数据状态：
          ```
          set_clusterState_active
          ```
          界面提示以下信息表示执行成功：
          ```
          hbase(main):001:0> set_clusterState_active
          => true
          ```
          
       
       2. 将主集群的HBase表数据从HDFS源目录导入到备集群的指定输出目录，并生成HFile文件：
          ```
          hbase org.apache.hadoop.hbase.mapreduce.Import -Dimport.bulk.output=备集群保存输出的目录 表名 备集群保存源数据的目录
          ```
          "-Dimport.bulk.output"指定的即为备集群中用于保存生成的HFile文件的目录。
          例如：
          ```
          hbase org.apache.hadoop.hbase.mapreduce.Import -Dimport.bulk.output=/user/hbase/output_t1 t1 /user/hbase/t1
          ```
          
       
       3. 将Import生成的HFile文件批量加载到备集群的目标HBase表中，完成数据同步：
          ```
          hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles 备集群保存输出的目录 表名
          ```
          例如：
          ```
          hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles /user/hbase/output_t1 t1
          ```
          
        
    
    
    
    

20. 在HBase客户端执行以下命令，校验主备集群同步的数据。启用容灾功能同步功能后，也可以执行该命令检验新的同步数据是否一致。 
    ```
    hbase org.apache.hadoop.hbase.mapreduce.replication.VerifyReplication --starttime=开始时间 --endtime=结束时间 列族名称 备集群ID 表名
    ```
    - 开始时间必须早于结束时间
    
    - 开始时间和结束时间需要填写时间戳的格式，例如执行**date -d "2015-09-30 00:00:00" +%s**将普通时间转化为时间戳格式。
    
    
    
    
**指定主备集群写数据状态。**
21. 在主集群**hb** **ase shell** 界面，使用"hbase"用户执行以下命令保持写数据状态。
    
    ```
    set_clusterState_active
    ```
    界面提示以下信息表示执行成功：
    ```
    hbase(main):001:0> set_clusterState_active
    => true
    ```
    
    
22. 在备集群**hbase** **shell** 界面，使用"hbase"用户执行以下命令保持只读数据状态。
    
    ```
    set_clusterState_standby
    ```
    界面提示以下信息表示执行成功：
    ```
    hbase(main):001:0> set_clusterState_standby
    => true
    ```
    
    
#### 相关命令
表2HBase容灾 
| 操作                                                                                 | 命令                                                                                                                                                                                                                                                                                                                           | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
|:---|:---|:---|
| 建立灾备关系                                                                             | ``` add_peer '备集群ID', CLUSTER_KEY => "备集群ZooKeeper业务ip地址", CONFIG => {"hbase.regionserver.kerberos.principal" => "备集群RegionServer principal", "hbase.master.kerberos.principal" => "备集群HMaster principal"} ``` 示例： ``` add_peer '1','zk1,zk2,zk3:2181:/hbase1' ``` **2181**表示集群中ZooKeeper的端口号。 | 建立主集群与备集群的关系，让其互相对应。 如果启用Bulkload批量写数据容灾还需执行： 1. 在备集群HDFS创建目录"/hbase/replicationConf/*主集群hbase.replication.cluster.id*"  2. 将主集群HBase客户端配置文件复制到备集群HDFS目录"/hbase/replicationConf/*主集群hbase.replication.cluster.id*"。                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| 移除灾备关系                                                                             | ``` remove_peer'备集群ID' ``` 示例： ``` remove_peer '1' ```                                                                                                                                                                                                                      | 在主集群中移除备集群的信息。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| 查询灾备关系                                                                             | ``` list_peers ```                                                                                                                                                                                                                                                                                                           | 在主集群中查询已经设置的备集群的信息，主要为ZooKeeper信息。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| 启用用户表实时同步                                                                          | ``` enable_table_replication '表名' ``` 示例： ``` enable_table_replication 't1' ```                                                                                                                                                                                             | 在主集群中，设置已存在的表同步到备集群。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| 禁用用户表实时同步                                                                          | ``` disable_table_replication '表名' ``` 示例： ``` disable_table_replication 't1' ```                                                                                                                                                                                           | 在主集群中，设置已存在的表不同步到备集群。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| 主备集群数据校验                                                                           | ``` bin/hbase org.apache.hadoop.hbase.mapreduce.replication.VerifyReplication --starttime=开始时间 --endtime=结束时间 列族名称 备集群ID 表名 ```                                                                                                                                                                                              | 检查指定的表在主备集群间的数据是否一致。 命令行中参数说明如下： - 开始时间：如果未设置，则取默认的开始时间为0。  - 结束时间：如果未设置，则取默认的结束时间为当前操作提交的时间。  - 表名：如果未输入表名，则默认校验所有的启用了实时同步的用户表。                                                                                                                                                                                                                                                                                                    |
| 切换数据写入状态                                                                           | - 将集群设置为写数据状态： ``` set_clusterState_active ```     - 将集群设置为只读数据状态： ``` set_clusterState_standby ```                        | 设置集群HBase表是否可写入数据。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| 新增或更新已经在对端集群保存的主集群中HDFS配置                                                          | ``` hdfs dfs -put -f HBase/hbase/conf/core-site.xml HBase/hbase/conf/hdfs-site.xml HBase/hbase/conf/yarn-site.xml hdfs://备集群NameNode IP:PORT/hbase/replicationConf/主集群hbase.replication.cluster.id ```                                                                                                                       | 启用包含Bulkload数据的容灾，在主集群修改HDFS参数时，新的参数值默认不会从主集群自动同步到备集群，需要手动执行命令同步。受影响的参数如下： - fs.defaultFS  - dfs.client.failover.proxy.provider.hacluster  - dfs.client.failover.connection.retries.on.timeouts  - dfs.client.failover.connection.retries   例如，"fs.defaultFS"值修改为"hdfs://hacluster_sale"；主集群HBase客户端配置文件，重新复制到备集群HDFS目录"/hbase/replicationConf/*主集群hbase.replication.cluster.id*"。 |
| 在开启批量加载数据复制功能（即"hbase.replication.bulkload.enabled"参数值为"true"）的情况下，禁用单表的批量加载数据复制能力 | ``` disable_bulkload_replication 'peerId','表名' ``` 示例： ``` disable_bulkload_replication '1','t1' ```                                                                                                                                                                                            | 主集群配置了Bulkload批量写数据容灾，并启用了用户表的实时同步能力，可使用该命令中断表的Bulkload数据同步能力。 *peerId* 可通过**list_peers**命令查看备集群信息获取，进行命令拼接。 仅MRS 3.3.0及之后版本支持。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| 在开启批量加载数据复制功能（即"hbase.replication.bulkload.enabled"参数值为"true"）的情况下，启用单表的批量加载数据能力   | ``` enable_bulkload_replication 'peerId','表名' ``` 示例： ``` enable_bulkload_replication '1','t1' ```                                                                                                                                                                                             | 主集群配置了Bulkload批量写数据容灾，并启用了用户表的实时同步能力，使用**disable_bulkload_replication**中断了该表的Bulkload数据同步后想再次开启Bulkload数据同步时，可使用该命令。 通过**get_peer_config** *'peerId* *'* 命令查看对应备集群容灾配置。其中以**BULREP_**前缀开头拼接表名的字段，对应值为"false"时，表明该表被禁用了Bulkload数据同步。 需注意： - 仅MRS 3.3.0及之后版本支持。  - 中断Bulkload数据同步期间的数据在重新开启后不会被同步。  - 由于该操作在服务端同步生效需要几分钟，为了避免同步时间差导致Bulkload数据丢失，可通过搜索RegionServer运行日志，确认执行该命令后RegionServer上均存在"Update peer configs succeed."日志打印，再开启后续主集群Bulkload数据操作。                                                                                                                 |
   
