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
- JavaScript 深入解剖bind內部機制JavaScript
- ElasticSearch 文件(document)內部機制詳解Elasticsearch
- js內部事件機制–單執行緒原理JS事件執行緒
- 通過WordCount解析Spark RDD內部原始碼機制Spark原始碼
- ElasticSearch內部基於_version樂觀鎖控制機制Elasticsearch
- Angular 中攔截器的真相和 HttpClient 內部機制AngularHTTPclient
- 模擬實現和深入理解Node Stream內部機制
- 探一探現代瀏覽器的內部機制(一)瀏覽器
- 智慧合約從入門到精通:Solidity的特性與內部機制Solid
- 探索計算機內部的神秘語言:二進位制的魅力計算機
- Redis處理客戶端連線的內部實現機制RXRedis客戶端
- 從template到DOM(Vue.js原始碼角度看內部執行機制)Vue.js原始碼
- 遊戲的藝術修養:加速通脹的內部經濟機制遊戲
- WPF原始碼分析系列一:剖析WPF模板機制的內部實現(一)原始碼
- WPF原始碼分析系列一:剖析WPF模板機制的內部實現(五)原始碼
- Hbase單機部署 java連線HbaseJava
- docker 內部如何訪問宿主機Docker
- ANA:內部機構持續崛起
- java內部類,區域性內部類,靜態內部類,匿名內部類Java
- 區塊鏈預言機(4)內在機制區塊鏈
- 10-Java內部類——成員內部類、區域性內部類、匿名內部類Java
- 內省機制(操作javaBean的資訊)JavaBean
- 極客程式設計師“怒斥”:FAANG 科技巨頭內部晉升機制正在“扼殺” Kubernetes!程式設計師
- 內部類與靜態內部類
- 由外到內——剖析Android訊息機制Android
- Java內部類詳解--匿名內部類Java
- HBase Memstore專屬JVM策略MSLAB機制深入剖析-OLAP商業環境實戰JVM
- 內部類
- 專題 | 專案管理知識、方法論、工具NO.6:企業內部的專案運作機制專案管理
- java內部類,為什麼需要內部類?Java
- Java內部類詳解-- 成員內部類Java
- 內部科技公司的挑戰與機遇(二)
- 使用釘釘建立企業內部機器人機器人
- Hbase單機版的安裝
- Java內部類詳解--區域性內部類Java
- Java 內部類Java
- 匿名內部類