Java代碼通過API操作HBase的最佳實踐


HBase提供了豐富的API。這使得用Java連接HBase非常方便。

有時候大家會使用HTable table=new HTable(config,tablename);的方式來實例化一個HTable對象,實際上這並不是最好的實例化HTable的辦法。最好的辦法是使用HTablePool,並且每個線程都使用獨立的HTable(參見《HBase The Definitive Guide》 4.4 HtablePool 和3.1 客戶端API 概述)。因為HTable實例的創建非常耗時,需要掃描.META表確認表是否存在,是否可用等,還需要做其他的一些操作,所以,最好在系統啟動的時候創建實例,如果需要多個HTable,考慮使用HTablePool。

比如我在webservice中,需要對HTable進行查詢,並將數據返回,我是這么做的:

可以在提供服務的類的構造函數里完成HTablePool的初始化,棄用下面的方法。

先在靜態代碼塊中把系統中需要用到的表都獲取一遍,獲取完之后立即關閉該表,以期增加真正的服務的代碼中,第一次實例化HTable對象的效率。

//這是我對外提供服務的類
public class HBaseQu
{

    // SignHBase.getConfiguration()是從配置文件中獲取
    //org.apache.hadoop.conf.Configuration的一個對象
    // 定義一個全局的HTablePool
    public static HTablePool hTablePool = new HTablePool(
            SignHBase.getConfiguration(), Integer.MAX_VALUE);
    // 初始化所用到的HTablePool,從pool中get一個需要用到的表,get完畢,立即關閉,
    // 以后每增加一個接口,如果需要用到一個新表的話,就在此處增加一次獲取表,然后關閉它的代碼。
    static
    {
           HTable table = null;
           //從池里獲取一個表,然后關閉它(類似於充血) try {
            table = (HTable) hTablePool.getTable(tableName);
            if (null != table)
            {
                table.close();
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

        //獲取另外一個表
        try
        {

           table = (HTable) hTablePool.getTable(tableName2);
           if (null != table) 
{
table.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}

 

在真正的服務的代碼中,直接使用pool.getTable(tableName)即可快速實例化該表。如下所示:

        HTable table = null;//定義HTable
        ResultScanner rs = null;//定義接收結果的ResultScanner對象
        try
        {
            //實例化HTable對象
            table = (HTable) HBaseQu.hTablePool.getTable(tablename);
            Scan s = new Scan();//實例化Scan對象
            s.setFilter(new PrefixFilter(rowPrifix.getBytes()));//添加過濾器
            s.addColumn(Bytes.toBytes(family), Bytes.toBytes(qualifier));          
            rs = table.getScanner(s);//獲取結果
            for (Result r : rs)
            {//循環處理行
                KeyValue[] kv = r.raw();
                for (int i = 0; i < kv.length; i++)
                {
                    value.add(new String(kv[i].getRow(), "UTF-8") + ":---:"
                            + new String(kv[i].getFamily()) + ":"
                            + new String(kv[i].getQualifier()) + ":---:"
                            + new String(kv[i].getValue()));

                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
        finally
        {
            //關閉打開的資源
            if (null != rs)
            {
                rs.close();
            }
            try
            {
                if (null != table)
                {
                    table.close();
                }
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    

 

 

 

 

 本文已同步至大數據技術http://cloudera.org.cn ),文章地址:http://cloudera.org.cn/?p=43


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM