如何配置HBase双读能力
操作场景
- 高成功率:双并发读机制,保证每一次读请求的成功率。
 - 可用性:单集群故障时,查询业务不中断。短暂的网络抖动也不会导致查询时间变长。
 - 通用性:双读特性不支持双写,但不影响原有的实时写场景。
 - 易用性:客户端封装处理,业务侧不感知。
 
 
    HBase双读使用约束:
- HBase双读特性基于Replication实现,备集群读取的数据可能和主集群存在差异,因此只能实现最终一致性。
 - 目前HBase双读功能仅用于查询。主集群宕机时,最新数据无法同步,备集群可能查询不到最新数据。
 - HBase的Scan操作可能分解为多次RPC。由于相关session信息在不同集群间不同步,数据不能保证完全一致,因此双读只在第一次RPC时生效,ResultScanner close之前的请求会固定访问第一次RPC时使用的集群。
 - HBase Admin接口、实时写入接口只会访问主集群。所以主集群宕机后,不能提供Admin接口功能和实时写入接口功能,只能提供Get、Scan查询服务。
 
操作步骤
- 参考准备连接HBase集群配置文件章节,获取HBase主集群客户端配置文件“core-site.xml”、“hbase-site.xml”、“hdfs-site.xml”,并将其放置到“src/main/resources/conf/active”目录下,该目录需要自己创建。
 - 参考准备连接HBase集群配置文件章节,获取备集群客户端配置文件“core-site.xml”、“hbase-site.xml”、“hdfs-site.xml”,并将其放置到“src/main/resources/conf/standby”目录下,该目录需要自己创建。
 - 创建“hbase-dual.xml”配置文件,放置到“src/main/resources/conf/”目录下。
    
    
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!--主集群配置文件目录--> <property> <name>hbase.dualclient.active.cluster.configuration.path</name> <value>{样例代码目录}\\src\\main\\resources\\conf\\active</value> </property> <!--备集群配置文件目录--> <property> <name>hbase.dualclient.standby.cluster.configuration.path</name> <value>{样例代码目录}\\src\\main\\resources\\conf\\standby</value> </property> <!--双读模式的Connection实现--> <property> <name>hbase.client.connection.impl</name> <value>org.apache.hadoop.hbase.client.HBaseMultiClusterConnectionImpl</value> </property> <!--普通模式--> <property> <name>hbase.security.authentication</name> <value>Simple</value> </property> <!--普通模式--> <property> <name>hadoop.security.authentication</name> <value>Simple</value> </property> 
代码样例
- 创建双读Configuration,下面代码片段在“com.huawei.bigdata.hbase.examples”包的“TestMain”类的init方法中添加。
    
private static void init() throws IOException { // Default load from conf directory conf = HBaseConfiguration.create(); //In Windows environment String userdir = TestMain.class.getClassLoader().getResource("conf").getPath() + File.separator; //In Linux environment //String userdir = System.getProperty("user.dir") + File.separator + "conf" + File.separator; conf.addResource(new Path(userdir + "hbase-dual.xml"), false); } - 确定数据来源的集群
    
- GET请求,以下代码片段在“com.huawei.bigdata.hbase.examples”包的“HBaseSample”类的testGet方法中添加。
      
Result result = table.get(get); if (result instanceof DualResult) { LOG.info(((DualResult)result).getClusterId()); } - Scan请求,以下代码片段在“com.huawei.bigdata.hbase.examples”包的“HBaseSample”类的testScanData方法中添加。
      
ResultScanner rScanner = table.getScanner(scan); if (rScanner instanceof HBaseMultiScanner) { LOG.info(((HBaseMultiScanner)rScanner).getClusterId()); } 
 - GET请求,以下代码片段在“com.huawei.bigdata.hbase.examples”包的“HBaseSample”类的testGet方法中添加。
      
 - 客户端支持打印metric信息
    
“log4j.properties”文件中增加如下内容,客户端将metric信息输出到指定文件。
log4j.logger.DUAL=debug,DUAL log4j.appender.DUAL=org.apache.log4j.RollingFileAppender log4j.appender.DUAL.File=/var/log/dual.log //客户端本地双读日志路径,根据实际路径修改,但目录要有写入权限 log4j.additivity.DUAL=false log4j.appender.DUAL.MaxFileSize=${hbase.log.maxfilesize} log4j.appender.DUAL.MaxBackupIndex=${hbase.log.maxbackupindex} log4j.appender.DUAL.layout=org.apache.log4j.PatternLayout log4j.appender.DUAL.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n 
HBase双读操作相关配置项说明
| 
        配置项名称  | 
      
        配置项详解  | 
      
        默认值  | 
      
        级别  | 
     
|---|---|---|---|
| 
        hbase.dualclient.active.cluster.configuration.path  | 
      
        主集群HBase客户端配置目录  | 
      
        无  | 
      
        必选配置  | 
     
| 
        hbase.dualclient.standby.cluster.configuration.path  | 
      
        备集群HBase客户端配置目录  | 
      
        无  | 
      
        必选配置  | 
     
| 
        dual.client.schedule.update.table.delay.second  | 
      
        更新开启容灾表列表的周期时间  | 
      
        5  | 
      
        可选配置  | 
     
| 
        hbase.dualclient.glitchtimeout.ms  | 
      
        可以容忍主集群的最大毛刺时间  | 
      
        50  | 
      
        可选配置  | 
     
| 
        hbase.dualclient.slow.query.timeout.ms  | 
      
        慢查询告警日志  | 
      
        180000  | 
      
        可选配置  | 
     
| 
        hbase.dualclient.active.cluster.id  | 
      
        主集群id  | 
      
        ACTIVE  | 
      
        可选配置  | 
     
| 
        hbase.dualclient.standby.cluster.id  | 
      
        备集群id  | 
      
        STANDBY  | 
      
        可选配置  | 
     
| 
        hbase.dualclient.active.executor.thread.max  | 
      
        请求主集群的线程池max大小  | 
      
        100  | 
      
        可选配置  | 
     
| 
        hbase.dualclient.active.executor.thread.core  | 
      
        请求主集群的线程池core大小  | 
      
        100  | 
      
        可选配置  | 
     
| 
        hbase.dualclient.active.executor.queue  | 
      
        请求主集群的线程池queue大小  | 
      
        256  | 
      
        可选配置  | 
     
| 
        hbase.dualclient.standby.executor.thread.max  | 
      
        请求备集群的线程池max大小  | 
      
        100  | 
      
        可选配置  | 
     
| 
        hbase.dualclient.standby.executor.thread.core  | 
      
        请求备集群的线程池core大小  | 
      
        100  | 
      
        可选配置  | 
     
| 
        hbase.dualclient.standby.executor.queue  | 
      
        请求备集群的线程池queue大小  | 
      
        256  | 
      
        可选配置  | 
     
| 
        hbase.dualclient.clear.executor.thread.max  | 
      
        清理资源线程池max大小  | 
      
        30  | 
      
        可选配置  | 
     
| 
        hbase.dualclient.clear.executor.thread.core  | 
      
        清理资源线程池core大小  | 
      
        30  | 
      
        可选配置  | 
     
| 
        hbase.dualclient.clear.executor.queue  | 
      
        清理资源线程池queue大小  | 
      
        Integer. MAX_VALUE  | 
      
        可选配置  | 
     
| 
        dual.client.metrics.enable  | 
      
        客户端metric信息是否打印  | 
      
        true  | 
      
        可选配置  | 
     
| 
        dual.client.schedule.metrics.second  | 
      
        客户端metric信息打印周期  | 
      
        300  | 
      
        可选配置  | 
     
| 
        dual.client.asynchronous.enable  | 
      
        是否异步请求主备集群  | 
      
        false  | 
      
        可选配置  | 
     
打印metric信息
| 
        Metric名称  | 
      
        描述  | 
      
        日志级别  | 
     
|---|---|---|
| 
        total_request_count  | 
      
        周期时间内查询总次数  | 
      
        INFO  | 
     
| 
        active_success_count  | 
      
        周期时间内主集群查询成功次数  | 
      
        INFO  | 
     
| 
        active_error_count  | 
      
        周期时间内主集群查询失败次数  | 
      
        INFO  | 
     
| 
        active_timeout_count  | 
      
        周期时间内主集群查询超时次数  | 
      
        INFO  | 
     
| 
        standby_success_count  | 
      
        周期时间内备集群查询成功次数  | 
      
        INFO  | 
     
| 
        standby_error_count  | 
      
        周期时间内备集群查询失败次数  | 
      
        INFO  | 
     
| 
        Active Thread pool  | 
      
        周期打印请求主集群的执行线程池信息  | 
      
        DEBUG  | 
     
| 
        Standby Thread pool  | 
      
        周期打印请求备集群的执行线程池信息  | 
      
        DEBUG  | 
     
| 
        Clear Thread pool  | 
      
        周期打印释放资源的执行线程池信息  | 
      
        DEBUG  | 
     
| 
        Metric名称  | 
      
        描述  | 
      
        日志级别  | 
     
|---|---|---|
| 
        averageLatency(ms)  | 
      
        平均时延  | 
      
        INFO  | 
     
| 
        minLatency(ms)  | 
      
        最小时延  | 
      
        INFO  | 
     
| 
        maxLatency(ms)  | 
      
        最大时延  | 
      
        INFO  | 
     
| 
        95thPercentileLatency(ms)  | 
      
        95%请求的最大时延  | 
      
        INFO  | 
     
| 
        99thPercentileLatency(ms)  | 
      
        99%请求的最大时延  | 
      
        INFO  | 
     
| 
        99.9PercentileLatency(ms)  | 
      
        99.9%请求的最大时延  | 
      
        INFO  | 
     
| 
        99.99PercentileLatency(ms)  | 
      
        99.99%请求的最大时延  | 
      
        INFO  |