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()
接下來的操作是到服務端的操作,這裏是流程圖