Thrift介紹與應用(三)—hbase的thrift介面
一、概述
Hbase是目前比較火的列儲存資料庫,由於Hbase是用Java寫的,因此它原生地提供了Java介面,對非Java程式人員,怎麼辦呢?幸好它提供了thrift介面伺服器,因此也可以採用其他語言來編寫Hbase的客戶端,本文即是Hbase C++介面的介紹。目前的Hbase(0.94.11,本文即基於此版本)有兩套thrift介面(可以叫thrift1和thrift2),它們並不相容(隨意性太強,這可能是所有開源軟體都具有的問題)。根據官方文件,thrift1很可能被拋棄,但網上的文章基本是介紹thrift1的,本文則主要介紹thrift2。
要使用Hbase的thrift介面,必須將它的服務啟動,命令列為:
thrift預設的監聽埠是9090,可以用netstat -nl | grep 9090看看該埠是否有服務。hbase-deamon.sh start thrift2
二、thrift1與thrift2的簡單比較
兩個版本的thrift檔案位於如下位置,src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift
src/main/resources/org/apache/hadoop/hbase/thrift2/hbase.thrift
thrift1的檔案有24K左右,而thrift2只有12K左右,看來新版做了大量的簡化。
名稱空間上,新版都將thrift改為thrift2,以示區別。下表是thrift和thrift2的區別,可以看出,二者真的差別挺大,特別是服務中的方法,thrift2做了簡化與合成,並把DDL有關的內容去掉了,關於這些結構、服務的具體意義,請參閱thrift檔案中的註釋,下文將詳細列出。
Thrift |
Thrift2 |
|
結構 |
struct TCell struct ColumnDescriptor struct TRegionInfo struct Mutation struct BatchMutation struct TIncrement struct TColumn struct TRowResult struct TScan |
struct TTimeRange struct TColumn struct TColumnValue struct TColumnIncrement struct TResult struct TGet struct TPut struct TDelete struct TIncrement struct TScan struct TRowMutations |
異常 |
exception IOError exception IllegalArgument exception AlreadyExists |
exception TIOError exception TIllegalArgument |
其他 |
union TMutation enum TDeleteType enum TDurability |
|
服務 |
名稱為:Hbase void enableTable() void disableTable() bool isTableEnabled() void compact() void majorCompact() list<Text> getTableNames() map<Text,ColumnDescriptor> getColumnDescriptors() list<TRegionInfo> getTableRegions() void createTable() void deleteTable() list<TCell> get() list<TCell> getVer() list<TCell> getVerTs() list<TRowResult> getRow() list<TRowResult> getRowWithColumns() list<TRowResult> getRowTs() list<TRowResult> getRowWithColumnsTs() list<TRowResult> getRows() list<TRowResult> getRowsWithColumns() list<TRowResult> getRowsTs() list<TRowResult> getRowsWithColumnsTs() void mutateRow() void mutateRowTs() void mutateRows() void mutateRowsTs() i64 atomicIncrement() void deleteAll() void deleteAllTs() void deleteAllRow() void increment() void incrementRows() void deleteAllRowTs() ScannerID scannerOpenWithScan() ScannerID scannerOpen() ScannerID scannerOpenWithStop() ScannerID scannerOpenWithPrefix() ScannerID scannerOpenTs() ScannerID scannerOpenWithStopTs() list<TRowResult> scannerGet() list<TRowResult> scannerGetList() void scannerClose() list<TCell> getRowOrBefore() TRegionInfo getRegionInfo() |
名稱為:THBaseService bool exists(...) TResult get(...) list<TResult> getMultiple(...) void put(...) bool checkAndPut(...) void putMultiple(...) void deleteSingle(...) list<TDelete> deleteMultiple(...) bool checkAndDelete(...) TResult increment(...) i32 openScanner(...) list<TResult> getScannerRows(...) void closeScanner(...) void mutateRow(...) list<TResult> getScannerResults(...) |
三、thrift2介面客戶端生成檔案
包含6個檔案hbase_constants.cpp/.h、 hbase_types.cpp/.h、THBaseService.cpp/.h,結構的定義都在hbase_types中,服務方法的實現在THBaseService中(關於這幾個檔案的詳細說明,見作者其他博文)。由於我們通常關心資料的查、增、刪(對Hbase來說,改是增加一個新“版本”),因此下面的討論只圍繞這些操作展開。
四、thrift2介面主要結構
以下是主要涉及的結構及其意義。
- TColumn 對列的封裝
- TColumnValue 對列及其值的封裝
- TResult 對單行(Row)及其查詢結果(若干colunmvalue)的封裝
- TGet 對查詢一行(row)的封裝,可以設定行內的查詢條件
- TPut 與TGet一樣,只是它是寫入若干“列”
- TDelete 與TGet一樣,只是它是刪除若干“列”
- TScan 對查詢多行和多列的封裝,有點類似於“cursor”
- TRowMutations 實際上是若干個TDelete和TPut的集合,完成對一行內資料的“原子”操作
五、thrift2介面service函式
1. 查資料
Service中有關查資料的函式如下:
- get:對某一行內的查詢,輸入是表名、TGet結構,輸出是TResult
- getMultiple:實際上是對get的擴充套件,輸入是表名、TGet陣列,輸出是TResult陣列
- openScanner、getScannerRows、closeScanner:這三個連在一起使用,類似於”cursor”,由openScanner開啟一個scanner,getScannerRows從這個開啟的scanner順序得到若干行(也就是一個TResult陣列,行數可指定),得不到資料行後可認為已讀完,最後用closeScanner關閉這個scanner。查詢的條件由TScan封裝,在開啟時傳入。需要注意的是每次取資料的行數要合適,否則有效率問題。
2. 增資料
Service中有關新增資料的函式如下:
- put:對某一行內增加若干列,輸入是表名,TPut結構
- putMultiple:對put的擴充套件,一次增加若干行內的若個列,輸入是表名、TPut陣列
- checkAndPut:這個函式比較有意思,它提供了一種“原子”操作的概念,當傳入的(表名+列族名+列名+資料)都存在於資料庫時,才做操作,返回true,否則不做任何操作而返回false。可以看出,Hbase內部實現這個操作時肯定是加鎖的。它使用的場合如下:某時刻一個使用者取得了某個值,以後只有在確保沒有其他人操作該值的情況下才能進行更新。
3. 刪資料
Service中有關刪除資料的函式如下:deleteSingle,deleteMultiple,checkAndDelete,這三個與上面的put函式類似,不再論述。
4. 其他
Service中其他的函式如下:
- exists:檢查表內是否存在某行或某行內某些列,輸入是表名、TGet,輸出是bool
- mutateRow:將某行內若干put和delete操作集合起來,形成一個“原子”操作。輸入是表名、TRowMutations結構。
- increment:增加一行內某些列的值,這個操作比較特別,是專門用於計數的,也保證了“原子”操作特性。
需要注意的是,以上大部分函式都是void,如果操作發生錯誤,thrift的做法是丟擲異常,因此進行操作時應有異常捕獲處理。
thrift2介面比較簡單明瞭,當然,實際使用時,會進行或多或少的再次封裝,以適應自己的應用需要,對該介面的再次封裝,這裡不在討論。