公司datalink平台负责从各种数据源读取数据并同步到其他的同步或者异构数据源,最近增加的HBase的reader利用到了Hbase的Replication特性。
正常情况下,我们配置HBase的Replication需要在主集群上Hbase的shell里进行如下一系列的配置。
登录到HMaster节点,打开Hbase的shell命令行,我们进行如下步骤:
1、打开主节点里要参与复制的表的列族的复制特性。
disable 'order_detail'
alter 'order_detail', {NAME => 'basic_info',REPLICATION_SCOPE => '1'},{NAME => 'ext_info', REPLICATION_SCOPE => '1'}
enable 'order_detail'
2、主节点里添加要复制的从节点的peer。
add_peer '2','10.102.22.33:2181:/hbase'
3、设置peer下的表、列族的复制关系。
set_peer_tableCFs '2','order_detail'
思考:
这些都是在Hbase的命令行里做的,我们的目标是通过管理平台能够做到更友好、更方便的管理,那有没有别的方式呢?
关于表的复制特性,我们建表的时候可以通过HBaseAdmin以代码的方式实现,即在建表时指定REPLICATION_SCOPE为1
其实在命令行建表最终也是通过HbaseAdmin实现的。
那显然在命令行中配置Replication一定也有对应的代码。通过翻阅代码和API我们找到了对应的实现类:ReplicationAdmin。
ReplicationAdmin是集群副本操作的Admin工具类,主要职责是增加删除查询 peer操作和设置peer同步表元数据TableCFs。
下面看下ReplicationAdmin的API:
方法名 | 参数 | 返回值 | 注解 | 备注 |
ReplicationAdmin | Configuration | ReplicationAdmin | 无 | 构造方法,参数Configuration为hbase集群链接配置信息 |
addPeer | String id String clusterKey | void | @Deprecated 已过期 | 添加副本集群的方法,参数解析 id:peer ID,在hbase集群中应唯一 clusterKey:副本集群,格式:zk_address:port:<zkHbaseParent> |
addPeer | String id String clusterKey String tableCFs | void | @Deprecated 已过期 | 添加副本集群的方法,参数解析 id:peer ID,在hbase集群中应唯一 clusterKey:副本集群,格式:zk_address:port:<zkHbaseParent> tableCFs:需要同步的表-列簇,格式:table_a:f1;table_a:f2;table_b:f1;table_b:f2 |
addPeer | String id ReplicationPeerConfig peerConfig Map<TableName,? extends Collection<String>> tableCfs | void | 无 | 添加副本集群的方法,参数解析 id: peer ID,在hbase集群中应唯一 peerConfig:副本集群配置封装,将副本集群地址封装到了peerConfig对象 tableCfs:需要同步的表-列簇,key 使用TableName对象表示,value使用 Collection<String> 实现类表示 |
removePeer | String id | void | 无 | 删除指定id的副本集群 |
enablePeer | String id | void | 无 | 使指定副本集群同步生效,生效后主集群才开始以rpc方式推送数据 |
disablePeer | String id | void | 无 | 使指定副本集群同步失效 |
getPeersCount | 无 | int | 无 | 返回当前集群副本集群数量 |
listPeers | 无 | Map<String,String> | @Deprecated 已过期 | 返回当前集群副本集合 Key:peer ID value:副本集群地址,格式:zk_address:port:<zkHbaseParent> |
listPeerConfigs | 无 | Map<String,ReplicationPeerConfig> | 无 | 返回当前集群副本集合 Key:peer ID value:ReplicationPeerConfig 副本封装对象,内部封装集群地址 |
getPeerConfig | String id | ReplicationPeerConfig | 无 | 返回指定副本集群的集群信息 |
getPeerTableCFs | String id | String | 无 | 返回指定副本集群的TableCFs信息,既所同步的表&表列簇。 |
setPeerTableCFs | String id String tableCFs | void | @Deprecated 已过期 | 设置指定副本集群,从主集群同步的表&表列簇。 tableCFs格式:table_a:f1;table_a:f2;table_b:f1;table_b:f2 |
setPeerTableCFs | String id Map<TableName,? extends Collection<String>> tableCfs | void | 无 | 设置指定副本集群,从主集群同步的表&表列簇。 tableCfs描述:需要同步的表-列簇,key 使用TableName对象表示,value使用 Collection<String> 实现类表示 |
getPeerState | String id | boolean | 无 | 获取指定Peer副本集群的,有效状态,enable状态返回true,否则返回false |
listReplicated | 无 | List<HashMap<String,String>> | 无 | 返回当前集群中,表-表列簇scope不为0的集合 key_1:"tableName" value_1:<tableName> key_2:"columnFamlyName" value_2:<columnName> key_3:"replicationType" value_3:<1> |
enableTableRep | final TableName tableName | void | 无 | 设置当前集群的指定表开启同步标记,既表的列簇全部设置scope为1; 该方法会查询peer列表中所有的集群,判断peer代表的副本集群是否拥有指定表,如果没有指定表,则从主集群复制表结构到该副本集群 |
disableTableRep | final TableName tableName | void | 无 | 设置当前集群的指定表关闭同步标记,既标的列簇全部设置scope为0 |
使用案例
/**
* 该用例添加集群10.102.22.33:2181:/hbase_0.98为当前集群的副本集群,peer id为test_repl_01
*/
@Test
public void exampleAddPeer() {
try{
Configuration configuration = HBaseManager.getConfiguration("framework");//内部代码,获取配置
ReplicationAdmin replicationAdmin = new ReplicationAdmin(configuration);
ReplicationPeerConfig peerConfig = new ReplicationPeerConfig();
peerConfig.setClusterKey("10.102.22.33:2181:/hbase_0.98");
replicationAdmin.addPeer("test_repl_01",peerConfig,null);
} catch (IOException e) {
e.printStackTrace();
} catch (ReplicationException e) {
e.printStackTrace();
}
}
/**
* 这段代码表示副本集群peer:"test_repl_01" 需要同步表example_table_one的列簇f1,f2
* 设置后,只要主集群的example_table_one表的f1,f2列簇的scope为1,peer:"test_repl_01"代表的集群即可同步数据
*/
@Test
public void exampleSetPeer() {
try {
Configuration configuration = HBaseManager.getConfiguration("framework");//内部代码,获取配置
ReplicationAdmin replicationAdmin = new ReplicationAdmin(configuration);
Map<TableName,List<String>> cfs = new HashMap<TableName,List<String>>();
TableName tableName = TableName.valueOf("example_table_one");
//key:tableName,value list;表示 table<example_table_one> 的列簇f1,f2 需要同步
cfs.put(tableName,Arrays.asList("f1","f2"));
//test_repl_01 为副本集群的唯一id
replicationAdmin.setPeerTableCFs("test_repl_01",cfs);
} catch (IOException e) {
e.printStackTrace();
} catch (ReplicationException e) {
e.printStackTrace();
}
}