第一部分:什麼是RPC
RPC (Remote Procedure Call Protocol) – 遠程過程協議調用 。通過 RPC 我們可以從網絡上的計算機請求服務,而不需要了 解底層網絡協議。 Hadoop 底層的交互都是通過 rpc 進行的。例 如: datanode 和 namenode 、 tasktracker和 jobtracker 、 secondary
namenode 和 namenode 之間的通信都是通過 rpc 實 現的。
RPC 模式
RPC 採用客戶機 / 服務器模式 。請求程序就是一個客戶機, 而服務提供程序就是一個服務器。首先,客戶機調用進程發送 一個有進程參數的調用信息到服務進程,然後等待應答信息。 在服務器端,進程保持睡眠狀態直到調用信息的到達爲止。當一個調用信息到達,服務器獲得進程參數,計算結果,發送答覆信息,然後等待下一個調用信息,最後, 客戶端調用進程接收答覆信息,獲得進程結果,然後調用執行繼續進行。
工作原理
運行時 , 一次客戶機對服務器的 RPC 調用 , 其內部操作大致有如下十步:
1. 調用客戶端句柄;執行傳送參數2. 調用本地系統內核發送網絡 消息3. 消息傳送到遠程 主機4. 服務器句柄得到消息並取得參數5. 執行遠程過程6. 執行的過程將結果返回服務器句柄7. 服務器句柄返回結果,調用遠程系統內核8. 消息傳回 本地主機9. 客戶句柄由內核接收消息10. 客戶接收句柄返回的數據
第二部分:Hadoop的RPC機制
Hadoop PRC
•Hadoop RPC在整個Hadoop中應用非常廣泛,Client、DataNode、NameNode之間的通訊全靠它了。舉個例子,我們平時操作HDFS的時候,使用的是FileSystem類,它的內部有個DFSClient對象,這個對象負責與NameNode打交道。在運行時,DFSClient在本地創建一個NameNode的代理,然後就操作這個代理,這個代理就會通過網絡,遠程調用到NameNode的方法,也能返回值。•Hadoop RPC 位於org.apache.hadoop.ipc•Hadoop RPC = 動態代理 + 定製好的二進制流•分爲Server與Clinet端
服務端流程
•Listener線程監視RPC Client發送過來的數據。•當有數據可以接收時,調用Connection的readAndProcess方法。• Connection邊接收邊對數據進行處理,如果接收到一個完整的Call包,則構建一個Call對象。PUSH到Call隊列中,由Handler線程來處理Call隊列中的所有Call。•Handler線程監聽Call隊列,如果Call隊列非空,按FIFO規則從Call隊列取出Call。•將Call交給RPC.Server處理。•藉助JDK提供的Method,完成對目標方法的調用,目標方法由具體的業務邏輯實現。•返回響應。Server.Handler按照異步非阻塞的方式向RPC Client發送響應,如果有未發送出的數據,則交由Server.Responder來完成。
服務端的接口
結構 功能 Server.Listener RPC Server的監聽者,用來接收RPC Client的連接請求和數據,其中數據封裝成Call後PUSH到Call隊列。 Server.Handler RPC Server的Call處理者,和Server.Listener通過Call隊列交互。 Server.Responder RPC Server的響應者。Server.Handler按照異步非阻塞的方式向RPC Client發送響應,如果有未發送出的數據,交由Server.Responder來完成。 Server.Connection RPC Server數據接收者。提供接收數據,解析數據包的功能。 Server.Call 持有客戶端的Call信息。
客戶端接口
第三部分:使用Hadoop RPC
結構 功能 Client.ConnectionId 到RPC Server對象連接的標識 Client.Call Call調用信息。 Client.ParallelResults Call響應。 RPC.Invoker 對InvocationHandler的實現,提供invoke方法,實現RPC Client對RPC Server對象的調用。 RPC.Invocation 用來序列化和反序列化RPC Client的調用信息。(主要應用JAVA的反射機制和InputStream/OutputStream)一些細節1. 根據 RPC Server 的 IP 與 PORT 從連接池中拿 Con2. 如果爲空,新建連接放到連接池3. 創建 Socket 建立到 Server 的連接4. 創建輸入輸出流對象5. 將序列化的參數發到服務端6. 等待服務端響應•客戶端發起的RPC調用是同步的,而服務端處理RPC調用是異步的。客戶端調用線程以阻塞同步的方式發起RPC連接及RPC調用,將參數等信息發送給Listener,然後等待Connection接收響應返回。•Listener負責接收RPC連接和RPC數據,當一個Call的數據接收完後,組裝成Call,並將Call放入由Handler提供的Call隊列中。•Handler線程監聽Call隊列,如果Call隊列不爲空,則按FIFO方式取出Call,並轉爲實際調用,以非阻塞方式將響應發回給Connection,未發送完畢的響應交給Responder處理。
流程•實現VersionedProtocol•繼承VersionedProtocol ,定義Server(即NameNode)•實現Clinet(即DataNode)實現VersionedProtocolpublic interface RPC Protocol Test extends VersionedProtocol {
public Text println(Text t);
}