HBase连接池 HTablePool被Deprecated之后

来源:互联网 发布:软媒win10优化工具 编辑:程序博客网 时间:2024/06/08 17:27


-

  • 说明: 最近两天在调研HBase的连接池,有了一些收获,特此记录下来。 本文先将官方文档(http://hbase.apache.org/book.html)9.3.1.1节翻译,方便大家阅读,然后查阅了关键类HConnectionManager的Developer API(http://hbase.apache.org/devapidocs/index.html) 做了一些总结。 最后介绍一些阅读0.96、0.98及最新源码的精彩发现。
    欢迎转载,请注明来源: http://blog.csdn.net/u010967382/article/details/38046821

    1.连接 HTable是HBase的client,负责从meta表中找到目标数据所在的RegionServers,当定位到目标RegionServers后,client直接和RegionServers交互,而不比再经过master。 HTable实例并不是线程安全的。当需要创建HTable实例时,明智的做法是使用相同的HBaseConfiguration实例,这使得共享连接到RegionServers的ZK和socket实例,例如,应该使用这样的代码:
    view sourceprint?
    1.HBaseConfiguration conf = HBaseConfiguration.create();
    2.HTable table1 =new HTable(conf, "myTable");
    3.HTable table2 =new HTable(conf, "myTable");
    而不是这样的代码:
    view sourceprint?
    1.HBaseConfiguration conf1 = HBaseConfiguration.create();
    2.HTable table1 =new HTable(conf1, "myTable");
    3.HBaseConfiguration conf2 = HBaseConfiguration.create();
    4.HTable table2 =new HTable(conf2, "myTable");


    2.连接池 当面对多线程访问需求时,我们可以预先建立HConnection,参见以下代码:

    Example 9.1. Pre-Creating a HConnection

    view sourceprint?
    1.// Create a connection to the cluster.
    2.HConnection connection = HConnectionManager.createConnection(Configuration);
    3.HTableInterface table = connection.getTable("myTable");
    4.// use table as needed, the table returned is lightweight
    5.table.close();
    6.// use the connection for other access to the cluster
    7.connection.close();
    构建HTableInterface实现是非常轻量级的,并且资源是可控的。
    注意: HTablePool是HBase连接池的老用法,该类在0.94,0.95和0.96中已经不建议使用,在0.98.1版本以后已经移除。
    BTW:简陋的官方文档到此为止。。。。Orz
    3.HConnectionManager 该类是连接池的关键,专门介绍。 HConnectionManager是一个不可实例化的类,专门用于创建HConnection。 最简单的创建HConnection实例的方式是HConnectionManager.createConnection(config),该方法创建了一个连接到集群的HConnection实例,该实例被创建的程序管理。通过这个HConnection实例,可以使用HConnection.getTable(byte[])方法取得HTableInterface implementations的实现,例如: HConnection connection = HConnectionManager.createConnection(config); HTableInterface table = connection.getTable("tablename");try { // Use the table as needed, for a single operation and a single thread }finally { table.close(); connection.close(); }
    3.1构造函数 无,不可实例化。
    3.2常用方法 (1)static HConnection createConnection(org.apache.hadoop.conf.Configuration conf) 创建一个新的HConnection实例。 该方法绕过了常规的HConnection生命周期管理,常规是通过getConnection(Configuration)来获取连接。调用方负责执行Closeable.close()来关闭获得的连接实例。 推荐的创建HConnection的方法是: HConnection connection = HConnectionManager.createConnection(conf); HTableInterface table = connection.getTable("mytable"); table.get(...); ... table.close(); connection.close();
    (2)public static HConnection getConnection(org.apache.hadoop.conf.Configuration conf) 根据conf获取连接实例。如果没有对应的连接实例存在,该方法创建一个新的连接。
    注意:该方法在0.96和0.98版本中都被Deprecated了,不建议使用,但是在最新的未发布代码版本中又复活了!!!
    3.3实例代码 package fulong.bigdata.hbase; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.client.HConnection; import org.apache.hadoop.hbase.client.HConnectionManager; import org.apache.hadoop.hbase.client.HTableInterface; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.ResultScanner; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.util.Bytes; public class ConnectionPoolTest { private static final StringQUORUM = "FBI001,FBI002,FBI003"; private static final StringCLIENTPORT = "2181"; private static final String TABLENAME = "rd_ns:itable";private static Configuration conf = null;private static HConnection conn = null;static{ try { conf = HBaseConfiguration.create();conf.set("hbase.zookeeper.quorum", QUORUM); conf.set("hbase.zookeeper.property.clientPort",CLIENTPORT); conn = HConnectionManager.createConnection(conf); }catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args)throws IOException { HTableInterface htable = ConnectionPoolTest.conn.getTable(TABLENAME);try { Scan scan = new Scan(); ResultScanner rs = htable.getScanner(scan);for (Result r : rs.next(5)) { for (Cell cell : r.rawCells()) { System.out.println("Rowkey : " + Bytes.toString(r.getRow()) + " Familiy:Quilifier : " + Bytes.toString(CellUtil.cloneQualifier(cell)) + " Value : " + Bytes.toString(CellUtil.cloneValue(cell)) + " Time : " + cell.getTimestamp()); } } } finally { htable.close(); } } }
    4.阅读源码的新发现 4.1消失的HConnectionManager.getConnection 从0.96和0.98版本HConnectionManager的源码中可以看到static final Map<HConnectionKey, HConnectionImplementation> CONNECTION_INSTANCES;
    就是连接池,连接池中的每个连接用HConnectionKey来标识。
    然而,我们来看已经被Deprecated的getConnection方法: /** * Get the connection that goes with the passed <code>conf</code> configuration instance. * If no current connection exists, method creates a new connection and keys it using * connection-specific properties from the passed {@link Configuration}; see * {@link HConnectionKey}. *@param conf configuration * @return HConnection object for <code>conf</code> *@throws ZooKeeperConnectionException */ @Deprecated public static HConnection getConnection(final Configuration conf)throws IOException { HConnectionKey connectionKey = new HConnectionKey(conf);synchronized (CONNECTION_INSTANCES) { HConnectionImplementation connection =CONNECTION_INSTANCES.get(connectionKey); if (connection ==null) { connection = (HConnectionImplementation)createConnection(conf,true); CONNECTION_INSTANCES.put(connectionKey, connection); }else if (connection.isClosed()) { HConnectionManager.deleteConnection(connectionKey,true); connection = (HConnectionImplementation)createConnection(conf,true); CONNECTION_INSTANCES.put(connectionKey, connection); } connection.incCount();return connection; } } 逻辑很简单:根据传入的conf构建HConnectionKey,然后到HConnectionKey中去查找,如果没有就新建,如果有并且被关闭,就删除再新建。 从中可以看到,HConnectionKey是根据conf来创建的,然而,我们的HBase集群的conf一般都不会有多个,除非你有多个HBase集群。 在这样一个机制下,如果只有一个conf,则连接池中永远只有一个connection实例!连接池也就没有任何意义了! 所以,代码中才将基于getConnection获取池中物的机制Deprecated了,转而在官方文档中建议: ******************************************************************************************************************* 当面对多线程访问需求时,我们可以预先建立HConnection,参见以下代码:

    Example 9.1. Pre-Creating a HConnection

    view sourceprint?
    1.<strong>// Create a connection to the cluster.
    2.HConnection connection = HConnectionManager.createConnection(Configuration);
    3.HTableInterface table = connection.getTable("myTable");
    4.// use table as needed, the table returned is lightweight
    5.table.close();
    6.// use the connection for other access to the cluster
    7.connection.close();</strong>
    构建HTableInterface实现是非常轻量级的,并且资源是可控的。 *******************************************************************************************************************
    (以上重新拷贝了一次官方文档的翻译) 如果大家按照官方文档的建议做了,也就是预先创建了一个连接,以后的访问都共享该连接,这样的效果其实和过去的getConnection完全一样,都是在玩一个connection实例!

    4.2 HBase的新时代 我查看了Git上最新版本的代码(https://git-wip-us.apache.org/repos/asf?p=hbase.git;a=tree),发现getConnection复活了: /** * Get the connection that goes with the passed <code>conf</code> configuration instance. * If no current connection exists, method creates a new connection and keys it using * connection-specific properties from the passed {@link Configuration}; see * {@link HConnectionKey}. *@param conf configuration * @return HConnection object for <code>conf</code> *@throws ZooKeeperConnectionException */ public static HConnection getConnection(final Configuration conf)throws IOException { return ConnectionManager.getConnectionInternal(conf); }

    这个不是重点,重点是最新版本代码的pom: 39 <groupId>org.apache.hbase</groupId> 40 <artifactId>hbase</artifactId> 41 <packaging>pom</packaging> 42 <version>2.0.0-SNAPSHOT</version> 43 <name>HBase</name> 44 <description> 45 Apache HBase\99 is the Hadoop database. Use it when you need 46 random, realtime read/write access to your Big Data. 47 This project's goal is the hosting of very large tables -- billions of rows X millions of columns -- atop clusters 48 of commodity hardware. 49 </description>
    HBase即将迎来2.0.0版本!! HBase的下一个发布版是否会像Hadoop2.0那样来一个华丽丽的升华,迎来众多牛逼的新特性呢? 从CHANGES.txt文档中没法得到最新的信息,最后一次更新还在2012年2月24日,看来开源大佬们也是爱编码不爱写文档的主。。
0 0
原创粉丝点击