如何配置HBase双读功能
操作场景
- 高成功率:双并发读机制,保证每一次读请求的成功率。
- 可用性:单集群故障时,查询业务不中断。短暂的网络抖动也不会导致查询时间变长。
- 通用性:双读特性不支持双写,但不影响原有的实时写场景。
- 易用性:客户端封装处理,业务侧不感知。
HBase双读使用约束:
- HBase双读特性基于Replication实现,备集群读取的数据可能和主集群存在差异,因此只能实现最终一致性。
- 目前HBase双读功能仅用于查询。主集群故障时,最新数据无法同步,备集群可能查询不到最新数据。
- HBase的Scan操作可能分解为多次RPC。由于相关session信息在不同集群间不同步,数据不能保证完全一致,因此双读只在第一次RPC时生效,ResultScanner close之前的请求会固定访问第一次RPC时使用的集群。
- HBase Admin接口、实时写入接口只会访问主集群。所以主集群故障后,不能提供Admin接口功能和实时写入接口功能,只能提供Get、Scan查询服务。
HBase双读支持以下两种方式设置主备集群的相关配置:
- 在“hbase-dual.xml”中新增主备集群的相关配置。
- 将主备集群相关配置设置到HBaseMultiClusterConnection中(仅MRS 3.3.0及之后版本支持)。
在“hbase-dual.xml”中新增主备集群配置
- 将在准备MRS应用开发用户时获取的主集群keytab认证文件“user.keytab”与“krb5.conf”放置到二次样例“src/main/resources/conf”目录下。
- 参考准备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/”目录下。配置文件中的配置项可参考HBase双读操作相关配置项说明。
<?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>kerberos</value> </property> <!--安全模式--> <property> <name>hadoop.security.authentication</name> <value>kerberos</value> </property>
- 创建双读Configuration。
- MRS 3.3.0之前版本,下面代码片段在“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); }
- MRS 3.3.0及之后版本,取消“com.huawei.bigdata.hbase.examples”包的“TestMain”类main方法中的testHBaseDualReadSample注释,确保“com.huawei.bigdata.hbase.examples”包的“HBaseDualReadSample”类中的“IS_CREATE_CONNECTION_BY_XML”值为“true”。
- MRS 3.3.0之前版本,下面代码片段在“com.huawei.bigdata.hbase.examples”包的“TestMain”类的init方法中添加。
- 确定数据来源的集群
- 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信息输出到指定文件。指标项信息可参考打印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
将主备集群相关配置设置到HBaseMultiClusterConnection中
该操作仅适用于MRS 3.3.0及之后版本。
- 将在准备MRS应用开发用户时获取的主集群keytab认证文件“user.keytab”与“krb5.conf”放置到二次样例“src/main/resources/conf”目录下。
- 创建双读Configuration,取消“com.huawei.bigdata.hbase.examples”包的“TestMain”类main方法中的testHBaseDualReadSample注释,确保“com.huawei.bigdata.hbase.examples”包的“HBaseDualReadSample”类中的“IS_CREATE_CONNECTION_BY_XML”值为“false”。
- 在“HBaseDualReadSample”类的addHbaseDualXmlParam方法中添加相关配置,相关配置项可参考HBase双读操作相关配置项说明。
private void addHbaseDualXmlParam(Configuration conf) { // We need to set the optional parameters contained in hbase-dual.xml to conf // when we use configuration transfer solution conf.set(CONNECTION_IMPL_KEY, DUAL_READ_CONNECTION); // conf.set("", ""); }
- 在“HBaseDualReadSample”类的initActiveConf方法中添加主集群客户端相关配置:
private void initActiveConf() { // The hbase-dual.xml configuration scheme is used to generate the client configuration of the active cluster. // In actual application development, you need to generate the client configuration of the active cluster. String activeDir = HBaseDualReadSample.class.getClassLoader().getResource(Utils.CONF_DIRECTORY).getPath() + File.separator + ACTIVE_DIRECTORY + File.separator; Configuration activeConf = Utils.createConfByUserDir(activeDir); HBaseMultiClusterConnection.setActiveConf(activeConf); }
- 在“HBaseDualReadSample”类initStandbyConf方法中添加备集群客户端相关配置:
private void initStandbyConf() { // The hbase-dual.xml configuration scheme is used to generate the client configuration of the standby cluster. // In actual application development, you need to generate the client configuration of the standby cluster. String standbyDir = HBaseDualReadSample.class.getClassLoader().getResource(Utils.CONF_DIRECTORY).getPath() + File.separator + STANDBY_DIRECTORY + File.separator; Configuration standbyConf = Utils.createConfByUserDir(standbyDir); HBaseMultiClusterConnection.setStandbyConf(standbyConf); }
- 确定数据来源的集群。
- 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信息输出到指定文件。指标项信息可参考打印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 |