Hbase Java Api
考虑是否可以使用自定义连接池来获取更好的性能表现?
对于高并发多线程访问的应用程序(例如,在单个 JVM 中存在的为多个线程服务的 Web 服务器或应用程序服务器), 只需要预先创建一个 Connection。Connection 是一个集群连接,封装了与多台服务器(Matser/Region Server)的底层连接以及与 zookeeper 的连接。 连接通过 ConnectionFactory 类实例化。连接的生命周期由调用者管理,调用者必须使用 close() 关闭连接以释放资源。
HBase 客户端需要连接三个不同的服务角色:
- Zookeeper :主要用于获取
meta表的位置信息,Master 的信息; - HBase Master :主要用于执行 HBaseAdmin 接口的一些操作,例如建表等;
- HBase RegionServer :用于读、写数据。


在 HBase 客户端,对应 Socket 连接的是 RpcConnection 对象。HBase 使用 PoolMap 这种数据结构来存储客户端到 HBase 服务器之间的连接。PoolMap 的内部有一个 ConcurrentHashMap 实例,其 key 是 ConnectionId(封装了服务器地址和用户 ticket),value 是一个 RpcConnection 对象的资源池。当 HBase 需要连接一个服务器时,首先会根据 ConnectionId 找到对应的连接池,然后从连接池中取出一个连接对象。
@InterfaceAudience.Private public class PoolMap<K, V> implements Map<K, V> { private PoolType poolType; private int poolMaxSize; private Map<K, Pool<V>> pools = new ConcurrentHashMap<>(); public PoolMap(PoolType poolType) { this.poolType = poolType; } .....
HBase 中提供了三种资源池的实现,分别是 Reusable,RoundRobin 和 ThreadLocal。具体实现可以通 hbase.client.ipc.pool.type 配置项指定,默认为 Reusable。连接池的大小也可以通过 hbase.client.ipc.pool.size 配置项指定,默认为 1,即每个 Server 1 个连接。也可以通过修改配置实现:
config.set("hbase.client.ipc.pool.type",...);
config.set("hbase.client.ipc.pool.size",...);
connection = ConnectionFactory.createConnection(config);
HBase 中 Connection 类已经实现对连接的管理功能,所以不必在 Connection 上在做额外的管理。
Connection 是线程安全的,但 Table 和 Admin 却不是线程安全的,因此正确的做法是一个进程共用一个 Connection 对象,而在不同的线程中使用单独的 Table 和 Admin 对象。Table 和 Admin 的获取操作 getTable() 和 getAdmin() 都是轻量级,不必担心性能的消耗,同时建议在使用完成后显示的调用 close() 方法来关闭它们。
浙公网安备 33010602011771号