首页 > 代码库 > HBase概念学习(九)HTablePool为何弃用?

HBase概念学习(九)HTablePool为何弃用?

转载请注明出处:jiq?钦‘s technical Blog

我们先看HConnection的getTable方法描述:

  • getTable

    HTableInterface getTable(String tableName)
                             throws IOException
    Retrieve an HTableInterface implementation for access to a table. The returned HTableInterface is not thread safe, a new instance should be created for each using thread. This is a lightweight operation, pooling or caching of the returned HTableInterface is neither required nor desired. Note that the HConnection needs to be unmanaged (created withHConnectionManager.createConnection(Configuration)).
    Parameters:
    tableName -
    Returns:
    an HTable to use for interactions with this table
    Throws:
    IOException
上面说HTable的的父类HTableInterface是非线程安全的,针对每个线程建议都应该创建一个新的HTableInterface实例,这个创建过程是轻量的,缓存HTableInterface对象既不是必须的也不是推荐的!


然后再联想到只要HTable使用的Configuration是同一个,那么它们一定是共用一个HConnection的,HConnection才是HBase客户端到Hbase集群的真正的连接。

再想想HTablePool的作用,无非就是HTable的连接池,里面维护的HTable应该来说都是使用的同一个HConnecion。

既然HTable的创建是轻量级的,使用同一个Confuguration的HTable都会共用一个HConnection,那么HTablePool就显得那么多余!


所以Hbase抛弃了HTablePool,我们唯一要做的就是保证HConnection实例是唯一的,全局共享的。然后针对HTableInterface对象最好在每次操作HBase表的时候根据HConnection对象来重新创建,使用完成之后及时关闭即可!


通过HConnection的getTable()方法就能够获取到用户操作HBase表的HTableInterface对象了。

下面是一个使用HConnection的getTable()方法获取HTableInterface对象的例子:

public void addUser(User user) throws IOException 
	{
		HTableInterface usersTable = conn.getTable(TABLE_NAME);
		
		Put put = makePut(user);		
		usersTable.put(put);
		
		usersTable.close();
		log.info("Add a User:"+user.name+" successfully");
	}

至于HConnection对象如何创建,HBase推荐使用的方法是:

  • createConnection

    public static HConnection createConnection(org.apache.hadoop.conf.Configuration conf)
                                        throws IOException
    Create a new HConnection instance using the passed conf instance.

    Note: This bypasses the usual HConnection life cycle management done by getConnection(Configuration). The caller is responsible for callingCloseable.close() on the returned connection instance. This is the recommended way to create HConnections.HConnection connection = HConnectionManager.createConnection(conf); HTableInterface table = connection.getTable("mytable"); table.get(...); ... table.close(); connection.close();

    Parameters:
    conf - configuration
    Returns:
    HConnection object for conf
    Throws:
    ZooKeeperConnectionException
    IOException
下面代码是我按照单例模式维护HConnection对象的例子:

public class HBaseUtils {

	private static final String QUORUM = "192.168.1.100";
	private static final String CLIENTPORT = "2181";
	private static Configuration conf = null;
	private static HConnection conn = null;
	
	/**
	 * 获取全局唯一的Configuration实例
	 * @return
	 */
	public static synchronized Configuration getConfiguration()
	{		
		if(conf == null)
		{
			conf =  HBaseConfiguration.create();
			conf.set("hbase.zookeeper.quorum", QUORUM); 
			conf.set("hbase.zookeeper.property.clientPort", CLIENTPORT);			
		}		
		return conf;				
	}
	
	/**
	 * 获取全局唯一的HConnection实例
	 * @return
	 * @throws ZooKeeperConnectionException
	 */
	public static synchronized HConnection getHConnection() throws ZooKeeperConnectionException
	{
		if(conn == null)
		{
			/*
			 * * 创建一个HConnection
			 * HConnection connection = HConnectionManager.createConnection(conf); 
			 * HTableInterface table = connection.getTable("mytable");
			 * table.get(...); ...
			 * table.close(); 
			 * connection.close();
			 * */
			conn = HConnectionManager.createConnection(getConfiguration());
		}
		
		return conn;
	}
}

以上属于个人见解,如果有什么疑问和指教,欢迎指正。

可以联系邮箱:jiq408694711@163.com 交流,季义钦