hbase java api 介紹 (2)

在很久以前的hbase java api介紹 (1)之後,
今天總算找時間寫了第二篇內容,
在此篇文章中, 將會敘述比較正規的java client寫作方式,
增進讀取hbase的效率, 以下是範例程式:

import java.io.*;
import java.net.*;
import java.util.*;
import java.lang.*;

import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.*;
import org.apache.hadoop.conf.Configuration;

public class hbasetest2
{
    public static Configuration conf;
    static
        {
        conf = HBaseConfiguration.create();
        conf.set("hbase.zookeeper.property.clientPort", "2222");
        conf.set("hbase.zookeeper.quorum", "master,slave01,slave02");
        conf.set("hbase.master", "master:600000");
    }

        static public void main(String[] args) throws Exception
        {
                String[] TableFamily = {"col1", "col2", "col3"};
                createHBaseTable("testTable", TableFamily);

                try
                {
                        HTablePool pool=new HTablePool(conf, 1000);
                        String key="key1";

                        Put put=new Put(key.getBytes());
                        put.add("col1".getBytes(), "qual1".getBytes(), "val1-1".getBytes());
                        put.add("col1".getBytes(), "qual2".getBytes(), "val1-2".getBytes());
                        put.add("col2".getBytes(), "qual3".getBytes(), "val2-3".getBytes());
                        (pool.getTable("testTable")).put(put);

                        String getResult="";
                        Get get=new Get(key.getBytes());
                        get.addColumn("col1".getBytes(), "qual1".getBytes());
                        get.addColumn("col2".getBytes(), "qual3".getBytes());
                        if( (pool.getTable("testTable")).exists(get) )
                        {
                                getResult = new String((pool.getTable("testTable")).get(get).getValue("col1".getBytes(), "qual1".getBytes()));
                                System.out.println("GET: " + getResult);
                                getResult = new String((pool.getTable("testTable")).get(get).getValue("col2".getBytes(), "qual3".getBytes()));
                                System.out.println("GET: " + getResult);
                                // getResult = new String((pool.getTable("testTable")).get(get).getValue("col1".getBytes(), "qual2".getBytes()));
                                // System.out.println("GET: " + getResult);
                        }

                        Delete delete=new Delete(key.getBytes());
                        (pool.getTable("testTable")).delete(delete);

                }
                catch (Exception e)
                {
                        System.out.println("Well..., something wrong with HBase");
                }


        }

        public static void createHBaseTable(String tablename, String[] families) throws IOException
        {
                HTableDescriptor htd = new HTableDescriptor(tablename);

                for(String fmly :families)
                {
                        HColumnDescriptor col = new HColumnDescriptor(fmly.getBytes());
                        col.setInMemory(true);
                        col.setMaxVersions(1);
                        htd.addFamily(col);
                }

                HBaseAdmin admin = new HBaseAdmin(conf);

                if (admin.tableExists(tablename))
                {
                        System.out.println("Table: " + tablename + "Existed.");
                        System.out.println("dropTable "+ tablename);

                        //drop the existing table
                        admin.disableTable(tablename);
                        admin.deleteTable(tablename);
                }

                admin.createTable(htd);
                System.out.println( tablename + " created.");
        }

}

在程式中, 首先我們宣告一個class作為創造table之用
public static void createHBaseTable(String tablename, String[] families) throws IOException
{
        HTableDescriptor htd = new HTableDescriptor(tablename);

        for(String fmly :families)
        {
        HColumnDescriptor col = new HColumnDescriptor(fmly.getBytes());
                col.setInMemory(true);
                col.setMaxVersions(1);
                htd.addFamily(col);
        }

        HBaseAdmin admin = new HBaseAdmin(conf);

        if (admin.tableExists(tablename))
        {
                System.out.println("Table: " + tablename + "Existed.");
                System.out.println("dropTable "+ tablename);

                //drop the existing table
                admin.disableTable(tablename);
                admin.deleteTable(tablename);
        }

        admin.createTable(htd);
        System.out.println( tablename + " created.");
}

在此物件中, 我們限制了所創立的table只記錄一筆timestample的資料:
col.setMaxVersions(1);
同時, 我們也把資料留在記憶體中, 加速存取
這裡要注意, 若是對於大量的NOSQL資料儲存, 請不要做相同的設置,
此外, 在建立table時, 若是table已經存在,
則先disable, 之後drop 所要創建的table,
藉由所宣告的CF表列與table名稱, 我們可以透過此物件創立table

對於put而言, 我們可以藉由宣告一個put物件
並將column的數值填入後, 一起put進入table, 減少建立連線的延遲,
程式如下:
Put put=new Put(key.getBytes());
put.add("col1".getBytes(), "qual1".getBytes(), "val1-1".getBytes());
put.add("col1".getBytes(), "qual2".getBytes(), "val1-2".getBytes());
put.add("col2".getBytes(), "qual3".getBytes(), "val2-3".getBytes());
(pool.getTable("testTable")).put(put);

當要get數值時, 我們也可以藉由get物件的宣告,
讀取一部分的row-key中的數值,
Get get=new Get(key.getBytes());
get.addColumn("col1".getBytes(), "qual1".getBytes());
get.addColumn("col2".getBytes(), "qual3".getBytes());
if( (pool.getTable("testTable")).exists(get) )
{
       getResult = new String((pool.getTable("testTable")).get(get).getValue("col1".getBytes(), "qual1".getBytes()));
       System.out.println("GET: " + getResult);
       getResult = new String((pool.getTable("testTable")).get(get).getValue("col2".getBytes(), "qual3".getBytes()));
       System.out.println("GET: " + getResult);
       //getResult = new String((pool.getTable("testTable")).get(get).getValue("col1".getBytes(), "qual2".getBytes()));
       //System.out.println("GET: " + getResult);
}

注意, 在這裡, 由於get物件中只有col1:qual1和col2:qual3兩個欄位,
因此, col1:qual2是讀不到的...
在hbase程式中, 要多利用(pool.getTable("testTable")).exists(get)來做判斷,
否則若有寫入和讀取衝突時, hbase程式會直接跳出至catch部分

最後是關於delete的部分,
delete是以row為單位, 所以對應的數值是row-key
Delete delete=new Delete(key.getBytes());
(pool.getTable("testTable")).delete(delete);

以上是這一次更新的內容,
以後若還有第三部分, 應該會說明scan和count的程式指令
希望可以有空完成...

留言

熱門文章

LTE筆記: RSRP, RSSI and RSRQ

[WiFi] WiFi 網路的識別: BSS, ESS, SSID, ESSID, BSSID

LTE筆記: 波束成型 (beamforming) 和天線陣列