HBaseThrift使用以及Thriftserver分析
對於thriftserver 我們主要從2個大的方面進行分析:thrift的使用;thriftserver的部署;thriftserver的啟動,初始化;thriftserver的讀寫等請求處理;
一:thrift的使用
Thrift的主要目的是方便各個語言可以使用HBase,java,c++,py,PHP,等等;在我們下載下來的hbase的檔案裡面的下面的目錄:
hbase/hbase-thrift/src/main/resources/org/apache/hadoop/hbase/thrift
你會看到2個資料夾,分別是:
hbase git:(hbase) ll */*
-rw-r--r-- 1 xxxxx xxxx 24K 8 15 09:40 thrift/Hbase.thrift
-rw-r--r-- 1 xxxxx xxxx 16K 8 15 09:40 thrift2/hbase.thrift
2個不同版本的Thrift檔案,有不同的區別,具體的區別參考連結的文章大概知道兩者的區別,這裡主要就一種的用法進行對應的介紹;
1>.首先要在自己的機器上面部署安裝thrift軟體;注意,服務端的thrift編譯環境和client需要一樣。我們雲HBase的Thrift的版本是0.9.0,所以希望你們編譯的thrift版本也是0.9.0,這樣以後進行互動才沒有問題;具體的安裝可以參考Thrift連結,也可以用別的方案,比如我是直接是用brew的命令列。
2>.thrift -gen php Hbase.thrift 會對應的在本地目錄下生產gen-py的對應的一個資料夾,如果是生產別的語言的話,使用別的命令,具體命令參考Thrift連結,當然這上面也有介紹thrift的安裝。
thrift git:(hbase) ll
total 56
-rw-r--r-- 1 xxxxx xxxx 24K 8 15 09:40 Hbase.thrift
drwxr-xr-x 4 xxxxx xxxx 136B 8 23 16:02 gen-php
我們需要的是gen-php的資料夾,當然,也可以生產c++,py,java等等;
3>.實際上在Hbase.thrift的檔案裡面已經有告訴我們怎麼使用這些函式以及資料結構,不如我最簡單的現在需要進行get操作;使用的是php語言的話,那麼thrift文件裡面有下面的介紹;
/**
* Get a single TCell for the specified table, row, and column at the
* latest timestamp. Returns an empty list if no such value exists.
*
* @return value for specified row/column
*/
list<TCell> get(
/** name of table */
1:Text tableName,
/** row key */
2:Text row,
/** column name */
3:Text column,
/** Get attributes */
4:map<Text, Text> attributes
) throws (1:IOError io)
/**
* TCell - Used to transport a cell value (byte[]) and the timestamp it was
* stored with together as a result for get and getRow methods. This promotes
* the timestamp of a cell to a first-class value, making it easy to take
* note of temporal data. Cell is used all the way from HStore up to HTable.
*/
struct TCell{
1:Bytes value,
2:i64 timestamp
}
上述的東西我們看到了,get方法,你需要人為的輸入table的name,row key,column 的name,以及你需要的些屬性,解釋的意思就是,get 一個單獨的cell,一列的資料;當然,如果你需要別的東西的話,那是另外的節後會有的;
4>.需要獲取得到thrift相關的依賴的庫,比如,Transport,Factory,Protocol等等,這個在thrift的最原始的包裡面會有的,但是還是要提醒下,一定要明確client 和服務端的thrift版本要一致,不然會出問題;
ini_set(`display_errors`, E_ALL);
$GLOBALS[`THRIFT_ROOT`] = `/root/hbase`;
require_once( $GLOBALS[`THRIFT_ROOT`] . `/Thrift.php` );
require_once( $GLOBALS[`THRIFT_ROOT`] . `/Thrift/transport/TSocket.php` );
require_once( $GLOBALS[`THRIFT_ROOT`] . `/Thrift/transport/TBufferedTransport.php` );
require_once( $GLOBALS[`THRIFT_ROOT`] . `/Thrift/protocol/TBinaryProtocol.php` );
require_once( $GLOBALS[`THRIFT_ROOT`] . `/gen-php/Hbase.php` );
$ip=xxxx;
$port=xx;
$socket = new TSocket($ip, $port);
$transport = new TBufferedTransport($socket);
$protocol = new TBinaryProtocol($transport);
$client = new HbaseClient($protocol);
$transport->open();
//case test
二:thriftserver的部署
關於hbase的thriftserver的部署,以及引數之類的這篇文章有介紹,這裡就不做介紹了。
上述文章中沒有對如果部署ThriftServer進行步驟性介紹,這裡介紹下,首先你下載了hbase-bin的二進位制包以後,你需要在本地搭建thriftservr的話,需要做3件事情:1.配置conf檔案,conf資料夾下的的hbase-site.xml檔案裡面需要配置下遠端的zk地址(遠端的hbase需要開啟本地的白名單);2.配置本地的thriftserver的堆記憶體,這個基於你的操作屬性進行設定,如果你的scan單次會涉及很多的資料,建議設定大等,不過一般都設定個128M就ok了,(ecs如果是記憶體足夠);3.到bin目錄下,執行sh hbase-daemon.sh start thrift 當然,這裡啟動哪個版本的thrift也是基於上面文章的介紹以及個人選擇進行的。然後就可以使用了。
四:Thriftserver的初始化啟動
最初的話,我們從最基本的啟動介面 開始入手看如何啟動Thriftserver,我們的啟動命令是sh hbas-deamon.sh start thrift/thrif2,啟動對應的thriftserver,我們可以進入最終啟動的bin目錄下的hbase的可執行檔案進行檢視,基於輸入的不同thrit 還是thrift2,啟動的是org.apache.hadoop.hbase.thrift.ThriftServer,org.apache.hadoop.hbase.thrift2.ThriftServer的這個class 檔案,這裡我們以簡單的org.apache.hadoop.hbase.thrift.ThriftServer進行對應的原始碼分析,分析啟動的時候做的操作,進入hbase的原始碼,以thriftserver的main方法進入:
public static void main(String [] args) throws Exception {
VersionInfo.logVersion();
try {
new ThriftServer(HBaseConfiguration.create()).doMain(args);
} catch (ExitCodeException ex) {
System.exit(ex.getExitCode());
}
}
以此為入口調到ThriftServerRunner內部的run方法,在這個函式內部我們會看到Thriftserver的初始化建立本地的server,包括設定使用與thrift的服務端相關資訊包括:TProtocolFactory,TProcessor,TTransportFactory等等基本資訊初始化完成,此外我們比較關心的就是這個thriftserver的server的初始化,這主要是基於不同的implType去建立,這裡預設使用的是THREAD_POOL 的方式的,我們以預設的方式往下看:
// Thread pool server. Get the IP address to bind to.
InetAddress listenAddress = getBindAddress(conf);
int readTimeout = conf.getInt(THRIFT_SERVER_SOCKET_READ_TIMEOUT_KEY,
THRIFT_SERVER_SOCKET_READ_TIMEOUT_DEFAULT);
TServerTransport serverTransport = new TServerSocket(
new TServerSocket.ServerSocketTransportArgs().
bindAddr(new InetSocketAddress(listenAddress, listenPort)).
backlog(backlog).
clientTimeout(readTimeout));
TBoundedThreadPoolServer.Args serverArgs =
new TBoundedThreadPoolServer.Args(serverTransport, conf);
serverArgs.processor(processor)
.transportFactory(transportFactory)
.protocolFactory(protocolFactory);
LOG.info("starting " + ImplType.THREAD_POOL.simpleClassName() + " on "
+ listenAddress + ":" + Integer.toString(listenPort)
+ " with readTimeout " + readTimeout + "ms; " + serverArgs);
TBoundedThreadPoolServer tserver =
new TBoundedThreadPoolServer(serverArgs, metrics);
this.tserver = tserver;
上述的程式碼,可以看到的就是,獲取得到繫結ip,預設是`0.0.0.0`,以及基於得到的埠(預設9090),設定的超時時間,設定好對應的TserverTransport,設定好相應的threadpoolserver的引數,然後設定好對應的初始化的server;這裡實際上這段程式碼以及對於thriftserver需要的ip port ,傳輸的thrift協議都設定好了(threadpoolserve內部也有對應的初始化的執行緒池),然後serve()方法內部會啟動對應的埠繫結以及初始化的執行緒池的操作,開始接受client的請求,可以理解的thriftserver的服務模型是,單執行緒的接收客戶端的請求,接收到請求,丟給後端的執行緒池進行操作;
上面大概介紹了預設的情況下,hbase的Thriftserver的啟動初始化,的相關操作,大概理順了一個流程,細節裡面的,各個操作的配置哪裡去取這些細小的地方,沒有描述;
三:thriftserver的呼叫
前段是thrift的處理,大概是從processer的process方法開始往下查,主要是從HBaseHandler進行觀測,比如get請求,落到這裡是get操作,我們看下面的程式碼:
protected List<TCell> get(ByteBuffer tableName,
ByteBuffer row,
byte[] family,
byte[] qualifier,
Map<ByteBuffer, ByteBuffer> attributes) throws IOError {
Table table = null;
try {
table = getTable(tableName);
Get get = new Get(getBytes(row));
addAttributes(get, attributes);
if (qualifier == null) {
get.addFamily(family);
} else {
get.addColumn(family, qualifier);
}
Result result = table.get(get);
return ThriftUtilities.cellFromHBase(result.rawCells());
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
throw getIOError(e);
} finally {
closeTable(table);
}
}
這裡往下看的話,實際上就和正常的java api的rpc請求一致了。其他的操作也是類似的。
相關文章
- CyclicBarrier、CountDownLatch以及Semaphore使用及其原理分析CountDownLatch
- Android中Parcel的分析以及使用Android
- Vue 中 $on $once $off $emit 詳細分析,以及使用VueMIT
- 使用SQL以及函式等做資料分析SQL函式
- Android記憶體洩露分析以及工具的使用Android記憶體洩露
- 前言以及迴歸分析
- 動態許可權的使用以及RxPermissions原始碼分析原始碼
- Goroutine 和 Channel 的的使用和一些坑以及案例分析Go
- vip原理以及使用
- mystat指令碼以及使用指令碼
- CentOSmysql安裝以及使用CentOSMySql
- GPU的介紹 以及原理的分析GPU
- Python呼叫C模組以及效能分析Python
- iOS開發之Crash分析,以及收集iOS
- Bug 報告的流程以及要素分析
- Serv-U漏洞以及原因分析(轉)
- Android/java 多執行緒(一)-Thread的使用以及原始碼分析AndroidJava執行緒thread原始碼
- Oracle RMAN備份以及壓縮原理分析Oracle
- HandlerThread解析以及相關問題分析thread
- Socks協議以及代理轉發工具分析協議
- 搶紅包案例分析以及程式碼實現
- Android 常用換膚方式以及原理分析Android
- PLSA模型的再理解以及原始碼分析模型原始碼
- mongodb的安裝以及使用MongoDB
- Java 封裝 SDK 以及使用Java封裝
- Promise作用以及基本使用Promise
- 微前端說明以及使用前端
- Guava ListenableFuture介紹以及使用Guava
- github的安裝以及使用Github
- iOS 封裝.framework 以及使用iOS封裝Framework
- Genymotion的安裝以及使用
- 使用Glide以及OkHttp整合IDEHTTP
- Jenkins部署以及基本使用Jenkins
- vue常量定義以及使用Vue
- 關於oracle11g RAC 監聽器使用中出現的no services以及no listener分析Oracle
- QQ快速登入協議分析以及風險反思協議
- Android HAL 層框架分析以及程式碼示例Android框架
- WebRTC現狀以及多人視訊通話分析Web