【深入淺出 Yarn 架構與實現】2-2 Yarn 基礎庫 - 底層通信庫 RPC

RPC(Remote Procedure Call) 是 Hadoop 服務通信的關鍵庫,支撐上層分布式環境下復雜的進程間(Inter-Process Communication, IPC)通信邏輯,是分布式系統的基礎 。允許運行于一臺計算機上的程序像調用本地方法一樣,調用另一臺計算機的子程序 。由于 RPC 服務整體知識較多 , 本節僅針對對 Yarn RPC 進行簡略介紹,詳細內容會后續開專欄介紹 。
一、RPC 通信模型介紹為什么會有 RPC 框架?在分布式或微服務情境下,會有大量的服務間交互,如果用傳統的 HTTP 協議端口來通信,需要耗費大量時間處理網絡數據交換上,還要考慮編解碼等問題 。如下圖所示 。

【深入淺出 Yarn 架構與實現】2-2 Yarn 基礎庫 - 底層通信庫 RPC

文章插圖
  • 客戶端通過 RPC 框架的動態代理得到一個代理類實例,稱為 Stub(樁)
  • 客戶端調用接口方法(實際是 Stub 對應的方法),Stub 會構造一個請求,包括函數名和參數
  • 服務端收到這個請求后,先將服務名(函數)解析出來,查找是否有對應的服務提供者
  • 服務端找到對應的實現類后,會傳入參數調用
  • 服務端 RPC 框架得到返回結果后,再進行封裝返回給客戶端
  • 客戶端的 Stub 收到返回值后,進行解析,返回給調用者,完成 RPC 調用 。
二、Hadoop RPC 介紹一)簡介Hadoop RPC 是 Hadoop 自己實現的一個 RPC 框架,主要有以下幾個特點:
  • 透明性:像調用本地方法一樣調用遠程方法 。
  • 高性能:Hadoop 各個系統均采用 Master/Slave 結構,Master 是一個 RPC Server 用于處理各個 Slave 節點發送的請求,需要有高性能 。
  • 可控性:由于 JDK 中的 RPC 框架 RMI 重量級過大,且封裝度太高,不方便控制和修改 。因此實現了自己的 RPC 框架,以保證輕量級、高性能、可控性 。
框架原理和整體執行流程與第一節介紹的 RPC 框架一致,感興趣可深入源碼進行了解 。
二)總體架構Hadoop RPC 架構底層依靠 Java 的 nio、反射、動態代理等功能實現「客戶端 - 服務器(C/S)」通信模型 。上層封裝供程序調用的 RPC 接口 。
【深入淺出 Yarn 架構與實現】2-2 Yarn 基礎庫 - 底層通信庫 RPC

文章插圖
三、案例 demo下面兩個案例的 demo 已上傳至 github 。有幫助的話點個? 。https://github.com/Simon-Ace/hadoop_rpc_demo
一)RPC Writable 案例實現1、新建一個 maven 工程,添加依賴
<dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>2.8.5</version></dependency>2、定義 RPC 協議
public interface BusinessProtocol {void mkdir(String path);String getName(String name);long versionID = 345043000L;}3、定義協議實現
public class BusinessIMPL implements BusinessProtocol {@Overridepublic void mkdir(String path) {System.out.println("成功創建了文件夾 :" + path);}@Overridepublic String getName(String name) {System.out.println("成功打了招呼: hello :" + name);return "bigdata";}}4、通過 Hadoop RPC 構建一個 RPC 服務端
import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.ipc.RPC;import java.io.IOException;public class MyServer {public static void main(String[] args) {try {// 構建一個 RPC server 端,提供了一個 BussinessProtocol 協議的 BusinessIMPL 服務實現RPC.Server server = new RPC.Builder(new Configuration()).setProtocol(BusinessProtocol.class).setInstance(new BusinessIMPL()).setBindAddress("localhost").setPort(6789).build();server.start();} catch (IOException e) {e.printStackTrace();}}}5、構建一個 RPC 客戶端
import org.apache.hadoop.ipc.RPC;import org.apache.hadoop.conf.Configuration;import java.io.IOException;import java.net.InetSocketAddress;public class MyClient {public static void main(String[] args) {try {// 獲取代理類實例,也就是 StubBusinessProtocol proxy = RPC.getProxy(BusinessProtocol.class, BusinessProtocol.versionID,new InetSocketAddress("localhost", 6789), new Configuration());// 通過 Stub 發送請求,實際使用就像調用本地方法一樣proxy.mkdir("/tmp/ABC");String res = proxy.getName("Simon");System.out.println("從 RPC 服務端接收到的返回值:" + res);} catch (IOException e) {e.printStackTrace();}}}6、測試,先啟動服務端,再啟動客戶端服務端輸出
成功創建了文件夾 :/tmp/ABC成功打了招呼: hello :Simon客戶端輸出
從 RPC 服務端接收到的返回值:bigdata二)RPC Protobuf 案例實現項目結構如下
【深入淺出 Yarn 架構與實現】2-2 Yarn 基礎庫 - 底層通信庫 RPC

文章插圖
對 proto 文件格式不熟悉的同學,參考上一篇文章《2-1 Yarn 基礎庫概述》

推薦閱讀