hbase put 源碼分析

get/delete/put/append/increment等等客戶可用的函數都在客戶端的HTable.java文件

HTable通過在connection調用getTable獲得,其實是調用HTable的構造方法創建一個HTable對象

HTable有幾個屬性要注意:

this.pool = pool; 線程池

this.rpcCallerFactory = rpcCallerFactory;

this.rpcControllerFactory = rpcControllerFactory;

rpc的控制工廠類

multiAp = this.connection.getAsyncProcess(); 異步處理的進程

this.locator = new HRegionLocator(tableName, connection); region的定位類

 

客戶端的put請求最後都是通過調用getBufferedMutator().mutate(put)

接下來的所有操作都是在BufferedMutatorImpl裏面完成,在BufferedMutatorImpl有一個AsyncProcess屬性ap

在操作中先對每個put的方法做預有效判斷,有效判斷後累加每個put的大小,並且緩存每個put到列表writeAsyncBuffer

在提交有做處理,當put的大小之和大於 hbase.client.write.buffer的值(默認爲2M),調用backgroundFlushCommits(false)進行提交

當ap報錯了,則強制提交backgroundFlushCommits(true)

在最後也會flush() 通過backgroundFlushCommits(true)進行強制提交

 

所有的提交都是通過ap.submit(tableName,writeAsyncBuffer,true,null,false) 完成

進入submit函數,可以看到它循環遍歷參數writeAsyncBuffer中的每一行,通過connection.locateRegion函數找到其在集羣的位置loc,將該位置與操作action一起綁定在變量actionByServer中。 

這裏的region定位是由ClusterConnection類型的變量connection完成的,進入其locateRegion方法可以看出,如果客戶端有緩存,則直接從緩存讀取,否則從META表中讀出了region所處的位置,並緩存此次的讀取結果。返回的結果是RegionLocations類型的變量。

actionByServer是一個Map<ServerName,MulteAction<Row>>類型的變量,從該變量的類型定義可以看出,其將用戶的一批寫請求中,寫入regionserver地址相同的動作歸類到一起。

注意:是所有針對同個server的所有操作都放在裏面,不是單個操作

 

最後調用sumitMultiActions函數將所有請求提交給服務端,它接受了上面的actionByServer作爲參數,內部實例化一個AsyncRequestFutureImpl類執行異步的提交動作

AsyncRequestFutureImpl.sendMultiAction()完成提交

在裏面創建一個SingleServerRequestRunnable對象,這個是個Runnable對象

 

在SingleServerRequestRunnable的run方法中,創建MultiServerCallable對象,用於實際將用戶請求與服務端建立聯繫,實際上

通過調用在SingleServerRequestRunnable的MultiServerCallable.callWithoutRetries()

在callWithoutRetries()裏面prepare()進行rpcClient的通道創建,call()提交邏輯

 

getStub().multi()

.ClientProtos.ClientService.BlockingStub

 

BlockingRpcChannelImplementation.callBlockingMethod()

 

RpcClientImpl.callBlockingMethod()

 

 

接下來的操作是到服務端的操作,這裏是流程圖

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章