1. 程式人生 > >HBase概念學習(九)HTablePool為何棄用?

HBase概念學習(九)HTablePool為何棄用?

轉載請註明出處:jiq•欽's technical Blog

使用HBase0.94版本號的時候提示HTablePool已經過時了。為什麼?

我們先看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 with
    HConnectionManager.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;
	}
}

以上屬於個人見解,假設有什麼疑問和不吝賜教,歡迎指正。

可以聯絡郵箱:[email protected] 交流,季義欽