2012年10月2日 星期二

Hbase之增刪查(shell&java)

前言
話說阿~~參加完Hadoop in Taiwan 2012後回家有感而發, 立馬把之前"草稿"很久的東西給"發佈"出來! Hbase也是有table概念的, 以下就是今天的目標:
table:scores -->table name
Row\key grade course -->column family

english music math history art chinese -->column family qualifier
pablo A






pablo
90





pablo

0




pablo


70



pablo



60


pablo




50

pablo





40


利用Hbase shell打造出以上的table, 不要對terminal中的畫面有太多幻想, 以上的表是我自己用Calc畫出來的, terminal中就是像下圖一樣, 




family , qualifier , row, key type....等等等的自己去找好兄弟google, 這些不在本篇的討論範圍, 因為blog都是筆記用, 不用來作學問XD


環境

這篇一樣
我的版本搭配是hadoop-1.0.3+hbase-0.94.1
PS:這篇沒有安裝zookeeper, 如果裝了zookeeper最下面的java對hbase做存取可能會出問題, 安裝可以參考這一篇

實作

[步驟一]
啟動大象, 啟動Hbase, 利用hbase shell指令進入Hbase操作畫面
等一下的table會叫做scores, 如果之前有自己建立過一樣名字的table請自己drop掉, 不drop掉的, 慢走不送了,  drop方式請見下圖, 務必先disable再drop

[步驟二]

按照我Calc中設計的建立table, 給予兩個column family{'grade' , 'course'}, course還要給qualifier... (我懶得打字自己對照上面的表), grade只是描述等級而已不給qualifier
以下是簡單說明要用到的shell結構:

建立table的shell:

create 'table name' , 'column family1' , 'column family2' , 'column family3'
今天的講師說column family最好不要超過三個.......(筆記)

寫入資料的shell結構是(在hbase shell打錯會有很大心的提示給你):

put 'table name' , 'row' , 'column family:qualifier' , 'value'

接下來就直接key一大堆指令了

1.建立table
create 'scores','grade','course'
2.對grade這一個column family加入value
put 'scores','pablo','grade','A'


3.對
course這一個column family底下的qualifier加入value

put 'scores','pablo','course:english','90'
put 'scores','pablo','course:music','0'
put 'scores','pablo','course:math','70'
put 'scores','pablo','course:history','60'
put 'scores','pablo','course:art','50'
put 'scores','pablo','course:chinese','40'

4.以上都輸入後,就用scan 'scores'來看看吧


眼睛尖的人是否有發現? 寫入Hbase後所有資料都排序了a-c-e-h-m-m, 沒錯~~
Table按Row key字典序排序如1,10,100,11,2,21,3......。


[步驟三]


以上shell操作就是那麼簡單, 接下來用java code來操作以上的shell指令 




import java.io.IOException;  
import java.util.ArrayList;  
import java.util.List;  
   
import org.apache.hadoop.conf.Configuration;  
import org.apache.hadoop.hbase.HBaseConfiguration;  
import org.apache.hadoop.hbase.HColumnDescriptor;  
import org.apache.hadoop.hbase.HTableDescriptor;  
import org.apache.hadoop.hbase.KeyValue;  
import org.apache.hadoop.hbase.MasterNotRunningException;  
import org.apache.hadoop.hbase.ZooKeeperConnectionException;  
import org.apache.hadoop.hbase.client.Delete;  
import org.apache.hadoop.hbase.client.Get;  
import org.apache.hadoop.hbase.client.HBaseAdmin;  
import org.apache.hadoop.hbase.client.HTable;  
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.client.Put;  
import org.apache.hadoop.hbase.util.Bytes; 

public class HBaseAnotherTest {

private static Configuration conf = null;  
    
    /*
     * 初始化HBASE_CONFIG配置, 使每個method共用一樣的配置
     */  
    static {  
        Configuration HBASE_CONFIG = new Configuration();  
        
        /*
         * 跟$HBASE_HOME/conf/hbase-site.xml中hbase.zookeeper.quorum屬性的值相同   
         */        
        HBASE_CONFIG.set("hbase.zookeeper.quorum", "HDP141,HDP142,HDP143");  
        
        /*
         * 跟$HBASE_HOME/conf/hbase-site.xml中hbase.zookeeper.property.clientPort屬性的值相同  
         */
        HBASE_CONFIG.set("hbase.zookeeper.property.clientPort", "2181");  
        conf = HBaseConfiguration.create(HBASE_CONFIG);  
    }  
      
    /** 
     * create table (create指令:create 'tableName','f2:q1','f1:q2','f2:q3'....)
     */  
    public static void creatTable(String tableName, String[] familys) throws Exception {  
        HBaseAdmin admin = new HBaseAdmin(conf);  
        if (admin.tableExists(tableName)) {  
            System.out.println("table already exists!");  
        } else {  
            HTableDescriptor tableDesc = new HTableDescriptor(tableName);  
            for(int i=0; i<familys.length; i++){  
                tableDesc.addFamily(new HColumnDescriptor(familys[i]));  
            }  
            admin.createTable(tableDesc);  
            System.out.println("create table " + tableName + " ok.");  
        }   
    }  
      
    /** 
     * delete table (先disable再drop)
     */  
    public static void deleteTable(String tableName) throws Exception {  
       try {  
           HBaseAdmin admin = new HBaseAdmin(conf);  
           admin.disableTable(tableName);  
           admin.deleteTable(tableName);  
           System.out.println("delete table " + tableName + " ok.");  
       } catch (MasterNotRunningException e) {  
           e.printStackTrace();  
       } catch (ZooKeeperConnectionException e) {  
           e.printStackTrace();  
       }  
    }  
       
    /** 
     * insert (put指令)
     */  
    public static void addRecord (String tableName, String rowKey, String family, String qualifier, String value) throws Exception{  
        try {  
            HTable table = new HTable(conf, tableName);  
            Put put = new Put(Bytes.toBytes(rowKey));  
            put.add(Bytes.toBytes(family),Bytes.toBytes(qualifier),Bytes.toBytes(value));  
            table.put(put);  
            System.out.println("insert recored " + rowKey + " to table " + tableName +" ok.");  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
   
    /** 
     * delete one row
     */  
    public static void delRecord (String tableName, String rowKey) throws IOException{  
        HTable table = new HTable(conf, tableName); 
List<Delete> list = new ArrayList<Delete>();  
        Delete del = new Delete(rowKey.getBytes());  
        list.add(del);  
        table.delete(list);  
        System.out.println("del recored " + rowKey + " ok.");  
    }  
       
    /** 
     * query one row (get指令:get 'tableName','column family:qualifier')
     */  
    public static void getOneRecord (String tableName, String rowKey) throws IOException{  
        HTable table = new HTable(conf, tableName);  
        Get get = new Get(rowKey.getBytes());  
        Result rs = table.get(get);  
        for(KeyValue kv : rs.raw()){  
            System.out.print(new String(kv.getRow()) + " " );  
            System.out.print(new String(kv.getFamily()) + ":" );  
            System.out.print(new String(kv.getQualifier()) + " " );  
            System.out.print(kv.getTimestamp() + " " );  
            System.out.println(new String(kv.getValue()));  
        }  
    }  
       
    /** 
     * list all (scan指令:scan 'tableName')
     */  
    public static void getAllRecord (String tableName) {  
        try{  
             HTable table = new HTable(conf, tableName);  
             Scan s = new Scan();  
             ResultScanner ss = table.getScanner(s);  
             for(Result r:ss){  
                 for(KeyValue kv : r.raw()){  
                    System.out.print(new String(kv.getRow()) + " ");  
                    System.out.print(new String(kv.getFamily()) + ":");  
                    System.out.print(new String(kv.getQualifier()) + " ");  
                    System.out.print(kv.getTimestamp() + " ");  
                    System.out.println(new String(kv.getValue()));  
                 }  
             }  
        } catch (IOException e){  
            e.printStackTrace();  
        }  
    }  
      
    public static void  main (String [] agrs) {  
        try {  
            String tablename = "scores";  
            String[] familys = {"grade", "course"};  
            HBaseAnotherTest.creatTable(tablename, familys);  
               
            /*
             * add record pablo
             * 
             *HBaseAnotherTest.addRecord("tablename","row","column family","column family qualifier","value");          
             */
            HBaseAnotherTest.addRecord(tablename,"pablo","grade","","A");  
            HBaseAnotherTest.addRecord(tablename,"pablo","course","english","90");  
            HBaseAnotherTest.addRecord(tablename,"pablo","course","music","0");  
            HBaseAnotherTest.addRecord(tablename,"pablo","course","math","70");  
            HBaseAnotherTest.addRecord(tablename,"pablo","course","history","60");  
            HBaseAnotherTest.addRecord(tablename,"pablo","course","art","50");
            HBaseAnotherTest.addRecord(tablename,"pablo","course","chinese","40");
               
            System.out.println("===========get one record========");  
            HBaseAnotherTest.getOneRecord(tablename, "pablo");  
               
            System.out.println("===========show all record========");  
            HBaseAnotherTest.getAllRecord(tablename);  
               
//            System.out.println("===========del one record========");  
//            HBaseAnotherTest.delRecord(tablename, "pablo");  
//            HBaseAnotherTest.getAllRecord(tablename);  
               
            System.out.println("===========show all record========");  
            HBaseAnotherTest.getAllRecord(tablename);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}

**補充**
透過客戶端程式碼存取組態檔:
以上程式碼中使用的HBaseConfiguration類別提供兩種靜態方法

1.static Configuration create()
  當呼叫此方法時背後的api會使用當前的classpath載入hbase-defuale.xmlhbase-site.xml
2.static Configuration create(Configuration conf)
   當呼叫此方法時指定一個現有個組態, 它的優先權會高於透過classpath所載入的設定檔



就把code貼到Eclipse中吧!run as hadoop前請先把之前用shell建立的table刪掉吧, 效果也是一樣的!


沒有留言:

張貼留言