天天看點

Hbase用戶端API基礎小結筆記(未完)

用戶端API:基礎

  HBase的主要用戶端接口是由org.apache.hadoop.hbase.client包中的HTable類提供的,通過這個類,使用者可以完成向HBase存儲和檢索資料,以及删除無效資料之類的操作。

  通常在正常負載下和正常操作下,用戶端讀操作不會受到其他修改資料的用戶端影響,因為它們之間的沖突可以忽略不計。但是,當允許用戶端需要同時修改同一行資料時就會産生問題。是以,使用者應當盡量使用批量處理(batch)更新來減少單獨操作同一行資料的次數。 (如果是實時系統,則需要加上synchronized關鍵字)

  建立HTable執行個體是有代價的。每個執行個體都需要掃描.META表,以檢查該表是否存在、是否可用,此外還要執行一些其他操作,這些檢查和操作導緻執行個體調用非常耗時,是以推薦使用者隻建立一次HTable執行個體(就好比在Hadoop的setup中建立一次執行個體,供後續mapreduce調用,最終在cleanup中close)

向HBase插入資料的example:

package HBaseTest;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;

/**
 * Created by root on 5/27/16.
 */
public class PutExample {
    public static void main(String[] args){
       //加載配置檔案
        Configuration conf = HBaseConfiguration.create();

        HTable table = null;
        try {
           //建立HTable對象
            table = new HTable(conf,"practice");
            //設定rowkey
            Put put = new Put(Bytes.toBytes("rowKeyNum1"));

            //設定要寫入的列族,列與value           
       put.add(Bytes.toBytes("f1"),Bytes.toBytes("cardNo"),Bytes.toBytes("123456789"));
 
            table.put(put);
            //擷取rowkey
            Get result = new Get("rowKeyNum1".getBytes());
            //将擷取到的值放入Hbase的Result中
            Result rs = table.get(result);
            //擷取指定列族的列的value
            String cardNo = Bytes.toString(rs.getValue("f1".getBytes(),"cardNo".getBytes()));
            System.out.println("---cardNo---" + cardNo);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}      
Hbase用戶端API基礎小結筆記(未完)

  資料和坐标都是以Java的byte[]形式存儲的,即以位元組數組的形式存儲的。使用這種底層存儲類型的目的是 ,允許存儲任意類型的資料,并且可以有效地隻存儲所需的位元組,這保證了最少的内部資料結構開銷。另一個原因是,每一個位元組數組都有一個offerset參數和一個length參數,它們允許使用者送出一個已存在的位元組數組,并進行效率很高的位元組級别的操作。

用戶端的寫緩沖區

  每一個put操作實際上都是一個RPC操作,它将用戶端資料傳送到伺服器然後傳回。這隻适合小資料量的操作,如果有個應用程式需要每秒存儲上千行資料到HBase表中,這樣的處理就不太合适了。(一般情況下,在LAN網絡中大概要花1毫秒的時間,這意味着1秒鐘的時間内隻能完成1000次RPC往返響應。)

  HBase的API配備了一個用戶端的寫緩沖區(write buffer),緩沖區負責收集put操作,然後調用RPC操作一次性将put送往伺服器。(預設情況下,用戶端緩沖區是禁用的,可以通過将自動刷寫autoflush設定為false來激活緩沖區)

HTable table = new HTable(conf,"practice");
 table.setAutoFlush(false);      

  用戶端寫緩沖區的大小預設是2MB,如果需要存儲較大的資料,為了避免每次建立執行個體都要修改緩沖區大小,可以在hbase-site.xml配置檔案中添加一個較大的預設值。

<property>
        <name>hbase.client.write.buffer</name>
        <value>20971520</value>
</property>      

  這會将緩沖區大小增肌到20MB,大小可以根據資料量等參考設定。

  強制刷寫資料可以調用table.flushCommits();直接産生一個RPC請求。

  注意:

  用戶端緩沖區是一個簡單的儲存在用戶端程序記憶體中的清單,使用者需要注意不能在運作時終止程式,如果發生這種情況,哪些尚未被刷寫的資料就會丢失,伺服器将無法收到資料,是以這些資料沒有任何副本可以用來做資料恢複。

  另外注意,一個更大的緩沖區需要用戶端和伺服器端消耗更多的記憶體,是以伺服器端也需要先将資料寫入到伺服器端消耗更多的記憶體,因為伺服器端也需要先将資料寫入到伺服器的寫緩沖區中,然後再處理它,估算伺服器端記憶體的占用可使用hbase.client.write.buffer 乘以 hbase.regionserver.handle.count 乘以region伺服器的數量。

  如果使用者隻存儲大單元格,用戶端緩沖區的作用就不大了,因為傳輸時間占用了大部分的請求時間。

 參考:《HBase權威指南》