HBase內部機制
背景
在HMaster、RegionServer內部,建立了RpcServer例項,並與Client三者之間實現了Rpc呼叫,HBase0.95內部引入了Google-Protobuf作為中間資料組織方式,並在Protobuf提供的Rpc介面之上,實現了基於服務的Rpc實現,本文詳細闡述了HBase-Rpc實現細節。
HBase的RPC Protocol
在HMaster、RegionServer內部,實現了rpc 多個protocol來完成管理和應用邏輯,具體如下protocol如下:
HMaster支援的Rpc協議:
MasterMonitorProtocol,Client與Master之間的通訊,Master是RpcServer端,主要實現HBase叢集監控的目的。
MasterAdminProtocol,Client與Master之間的通訊,Master是RpcServer端,主要實現HBase表格的管理。例如TableSchema的更改,Table-Region的遷移、合併、下線(Offline)、上線(Online)以及負載平衡,以及Table的刪除、快照等相關功能。
RegionServerStatusProtoco,RegionServer與Master之間的通訊,Master是RpcServer端,負責提供RegionServer向HMaster狀態彙報的服務。
RegionServer支援的Rpc協議:
ClientProtocol,Client與RegionServer之間的通訊,RegionServer是RpcServer端,主要實現使用者的讀寫請求。例如get、multiGet、mutate、scan、bulkLoadHFile、執行Coprocessor等。
AdminProtocols,Client與RegionServer之間的通訊,RegionServer是RpcServer端,主要實現Region、服務、檔案的管理。例如storefile資訊、Region的操作、WAL操作、Server的開關等。
(備註:以上提到的Client可以是使用者Api、也可以是RegionServer或者HMaster)
HBase-RPC實現機制分析
RpcServer配置三個佇列:
1)普通佇列callQueue,絕大部分Call請求存在該佇列中:callQueue上maxQueueLength為${ipc.server.max.callqueue.length},預設是${hbase.master.handler.count}*DEFAULT_MAX_CALLQUEUE_LENGTH_PER_HANDLER,目前0.95.1中,每個Handler上CallQueue的最大個數預設值(DEFAULT_MAX_CALLQUEUE_LENGTH_PER_HANDLER)為10。
2)優先順序佇列: PriorityQueue。如果設定priorityHandlerCount的個數,會建立與callQueue相當容量的queue儲存Call,該優先順序佇列對應的Handler的個數由rpcServer例項化時傳入。
3)拷貝佇列:replicationQueue。由於RpcServer由HMaster和RegionServer共用,該功能僅為RegionServer提供,queue的大小為${ipc.server.max.callqueue.size}指定,預設為1024*1024*1024,handler的個數為hbase.regionserver.replication.handler.count。
RpcServer由三個模組組成:
Listener ===Queue=== Responder
這裡以HBaseAdmin.listTables為例,分析一個Rpc請求的函式呼叫過程:
1) RpcClient建立一個BlockingRpcChannel。
2)以channel為引數建立執行RPC請求需要的stub,此時的stub已經被封裝在具體Service下,stub下定義了可執行的rpc介面。
3)stub呼叫對應的介面,實際內部channel呼叫callBlockingMethod方法。
RpcClient內實現了protobuf提供的BlockingRpcChannel介面方法callBlockingMethod,
@Overridepublic Message callBlockingMethod(MethodDescriptor md, RpcController controller,Message param, Message returnType)throws ServiceException {return this.rpcClient.callBlockingMethod(md, controller, param, returnType, this.ticket,this.isa, this.rpcTimeout);}
通過以上的實現細節,最終轉換成rpcClient的呼叫,使用MethodDescriptor封裝了不同rpc函式,使用Message基類可以接收基於Message的不同的Request和Response物件。
4)RpcClient建立Call物件,查詢或者建立合適的Connection,並喚醒Connection。
5)Connection等待Call的Response,同時rpcClient呼叫函式中,會使用connection.writeRequest(Call call)將請求寫入到RpcServer網路流中。
6)等待Call的Response,然後層層返回給更上層介面,從而完成此次RPC呼叫。
RPCServer收到的Rpc報文的內部組織如下:
Magic (4Byte) |
Version (1Byte) |
AuthMethod (1Byte) |
Connection HeaderLength (4Byte) |
ConnectionHeader |
Request |
“HBas” |
|||||
驗證RpcServer的CURRENT_VERSION 與RPC報文一致 |
目前支援三類: AuthMethod.SIMPLE AuthMethod.KERBEROS AuthMethod.DIGEST |
RPC.proto定義 |
整個Request儲存是經過編碼之後的byte陣列,包括如下幾個部分:
RequestHeaderLength(RawVarint32) |
RequestHeader |
ParamSize(RawVarint32) |
Param |
CellScanner |
RPC.proto定義: |
Protobuf的基本型別Message, |
從功能上講,RpcServer上包含了三個模組,
1)Listener。包含了多個Reader執行緒,通過Selector獲取ServerSocketChannel接收來自RpcClient傳送來的Connection,並從中重構Call例項,新增到CallQueue佇列中。
”IPC Server listener on 60021″ daemon prio=10 tid=0x00007f7210a97800 nid=0x14c6 runnable [0x00007f720e8d0000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
- locked <0x00000000c43cae68> (a sun.nio.ch.Util$2)
- locked <0x00000000c43cae50> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000c4322ca8> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:84)
at org.apache.hadoop.hbase.ipc.RpcServer$Listener.run(RpcServer.java:646)
2)Handler。負責執行Call,呼叫Service的方法,然後返回Pair<Message,CellScanner>
“IPC Server handler 0 on 60021″ daemon prio=10 tid=0x00007f7210eab000 nid=0x14c7 waiting on condition [0x00007f720e7cf000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000c43cad90> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1987)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:399)
at org.apache.hadoop.hbase.ipc.RpcServer$Handler.run(RpcServer.java:1804)
3) Responder。負責把Call的結果返回給RpcClient。
”IPC Server Responder” daemon prio=10 tid=0x00007f7210a97000 nid=0x14c5 runnable [0x00007f720e9d1000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
- locked <0x00000000c4407078> (a sun.nio.ch.Util$2)
- locked <0x00000000c4407060> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000c4345b68> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
at org.apache.hadoop.hbase.ipc.RpcServer$Responder.doRunLoop(RpcServer.java:833)
at org.apache.hadoop.hbase.ipc.RpcServer$Responder.run(RpcServer.java:816)
RpcClient為Rpc請求建立Connection,通過Connection將Call傳送RpcServer,然後RpcClient等待結果的返回。
相關文章
- redis 內部機制Redis
- IIS 內部執行機制
- JavaScript 深入解剖bind內部機制JavaScript
- HashMap的內部實現機制HashMap
- ElasticSearch 文件(document)內部機制詳解Elasticsearch
- buffer cache 內部機制深入探索【一】
- Library cache內部機制詳解
- new和instanceof的內部機制
- Oracle Library cache內部機制詳解Oracle
- js內部事件機制–單執行緒原理JS事件執行緒
- 通過WordCount解析Spark RDD內部原始碼機制Spark原始碼
- ElasticSearch內部基於_version樂觀鎖控制機制Elasticsearch
- zt_Oracle Library cache 內部機制 說明Oracle
- Angular 中攔截器的真相和 HttpClient 內部機制AngularHTTPclient
- 理解Window的新增,刪除,重新整理內部機制
- C#泛型內部工作機制詳細解析C#泛型
- 模擬實現和深入理解Node Stream內部機制
- 搭建高可用MongoDB叢集(三):深入副本集內部機制MongoDB
- 我對備份與恢復的內部機制的理解
- HBase 事務和併發控制機制原理
- 探一探現代瀏覽器的內部機制(一)瀏覽器
- HBase最佳實踐-客戶端超時機制客戶端
- 遊戲的藝術修養:加速通脹的內部經濟機制遊戲
- 探索計算機內部的神秘語言:二進位制的魅力計算機
- Redis處理客戶端連線的內部實現機制RXRedis客戶端
- oracle中dump函式及oracle NUMBER型別內部儲存機制Oracle函式型別
- 從template到DOM(Vue.js原始碼角度看內部執行機制)Vue.js原始碼
- WPF原始碼分析系列一:剖析WPF模板機制的內部實現(一)原始碼
- WPF原始碼分析系列一:剖析WPF模板機制的內部實現(五)原始碼
- 智慧合約從入門到精通:Solidity的特性與內部機制Solid
- JavaScript工作機制:V8 引擎內部機制及如何編寫優化程式碼的5個訣竅JavaScript優化
- zt_阿里張瑞jacky關於library cache的內部管理機制阿里
- docker 內部如何訪問宿主機Docker
- Hbase單機部署 java連線HbaseJava
- 快手CEO宿華內部郵件曝光 平臺生態加強淨化機制
- Elasticserach---寫一致性原理以及quorum機制---以及內部查詢原理AST
- React 內部機制探祕 - React Component 和 Element(文末附彩蛋demo和原始碼)React原始碼
- java內部類,區域性內部類,靜態內部類,匿名內部類Java