Hadoop RPC机制的使用
一、RPC基礎概念
1.1 RPC的基礎概念
RPC,即Remote Procdure Call,中文名:遠程過程調用;
(1)它允許一臺計算機程序遠程調用另外一臺計算機的子程序,而不用去關心底層的網絡通信細節,對我們來說是透明的。因此,它經常用于分布式網絡通信中。
RPC協議假定某些傳輸協議的存在,如TCP或UDP,為通信程序之間攜帶信息數據。在OSI網絡通信模型中,RPC跨越了傳輸層和應用層。RPC使得開發包括網絡分布式多程序在內的應用程序更加容易。
(2)Hadoop的進程間交互都是通過RPC來進行的,比如Namenode與Datanode直接,Jobtracker與Tasktracker之間等。
因此,可以說:Hadoop的運行就是建立在RPC基礎之上的。
1.2 RPC的顯著特點
(1)透明性:遠程調用其他機器上的程序,對用戶來說就像是調用本地方法一樣;
(2)高性能:RPC Server能夠并發處理多個來自Client的請求;
(3)可控性:jdk中已經提供了一個RPC框架—RMI,但是該PRC框架過于重量級并且可控之處比較少,所以Hadoop RPC實現了自定義的PRC框架。
1.3 RPC的基本流程
(1)RPC采用了C/S的模式;
(2)Client端發送一個帶有參數的請求信息到Server;
(3)Server接收到這個請求以后,根據發送過來的參數調用相應的程序,然后把自己計算好的結果發送給Client端;
(4)Client端接收到結果后繼續運行;
1.4 Hadoop中的RPC機制
同其他RPC框架一樣,Hadoop RPC分為四個部分:
(1)序列化層:Clent與Server端通信傳遞的信息采用了Hadoop里提供的序列化類或自定義的Writable類型;
(2)函數調用層:Hadoop RPC通過動態代理以及java反射實現函數調用;
(3)網絡傳輸層:Hadoop RPC采用了基于TCP/IP的socket機制;
(4)服務器端框架層:RPC?Server利用java NIO以及采用了事件驅動的I/O模型,提高RPC Server的并發處理能力;
Hadoop RPC在整個Hadoop中應用非常廣泛,Client、DataNode、NameNode之間的通訊全靠它了。例如:我們平時操作HDFS的時候,使用的是FileSystem類,它的內部有個DFSClient對象,這個對象負責與NameNode打交道。在運行時,DFSClient在本地創建一個NameNode的代理,然后就操作這個代理,這個代理就會通過網絡,遠程調用到NameNode的方法,也能返回值。
1.5 Hadoop RPC設計技術
(1)動態代理
About:動態代理可以提供對另一個對象的訪問,同時隱藏實際對象的具體事實,代理對象對客戶隱藏了實際對象。目前Java開發包中提供了對動態代理的支持,但現在只支持對接口的實現。
(2)反射——動態加載類
(3)序列化
(4)非阻塞的異步IO(NIO)
Java NIO原理請參考閱讀:http://weixiaolu.iteye.com/blog/1479656
二、如何使用RPC
2.1 Hadoop RPC對外提供的接口
Hadoop RPC對外主要提供了兩種接口(見類org.apache.hadoop.ipc.RPC),分別是:
(1)public static <T> ProtocolProxy <T> getProxy/waitForProxy(…)
構造一個客戶端代理對象(該對象實現了某個協議),用于向服務器發送RPC請求。
(2)public static Server RPC.Builder (Configuration).build()
為某個協議(實際上是Java接口)實例構造一個服務器對象,用于處理客戶端發送的請求。
2.2 使用Hadoop RPC的四大步湊
(1)定義RPC協議
RPC協議是客戶端和服務器端之間的通信接口,它定義了服務器端對外提供的服務接口。
(2)實現RPC協議
Hadoop RPC協議通常是一個Java接口,用戶需要實現該接口。
(3)構造和啟動RPC SERVER
直接使用靜態類Builder構造一個RPC Server,并調用函數start()啟動該Server。
(4)構造RPC Client并發送請求
使用靜態方法getProxy構造客戶端代理對象,直接通過代理對象調用遠程端的方法。
三、RPC應用實例
3.1 定義RPC協議
如下所示,我們定義一個IProxyProtocol?通信接口,聲明了一個Add()方法。
public interface IProxyProtocol extends VersionedProtocol {static final long VERSION = 23234L; //版本號,默認情況下,不同版本號的RPC Client和Server之間不能相互通信int Add(int number1,int number2); }需要注意的是:
(1)Hadoop中所有自定義RPC接口都需要繼承VersionedProtocol接口,它描述了協議的版本信息。
(2)默認情況下,不同版本號的RPC Client和Server之間不能相互通信,因此客戶端和服務端通過版本號標識。
3.2 實現RPC協議
Hadoop RPC協議通常是一個Java接口,用戶需要實現該接口。對IProxyProtocol接口進行簡單的實現如下所示:
public class MyProxy implements IProxyProtocol {public int Add(int number1,int number2) {System.out.println("我被調用了!");int result = number1+number2;return result;}public long getProtocolVersion(String protocol, long clientVersion)throws IOException {System.out.println("MyProxy.ProtocolVersion=" + IProxyProtocol.VERSION);// 注意:這里返回的版本號與客戶端提供的版本號需保持一致return IProxyProtocol.VERSION;} }這里實現的Add方法很簡單,就是一個加法操作。為了查看效果,這里通過控制臺輸出一句:“我被調用了!”
3.3 構造RPC Server并啟動服務
這里通過RPC的靜態方法getServer來獲得Server對象,如下代碼所示:
public class MyServer {public static int PORT = 5432;public static String IPAddress = "127.0.0.1";public static void main(String[] args) throws Exception {MyProxy proxy = new MyProxy();final Server server = RPC.getServer(proxy, IPAddress, PORT, new Configuration());server.start();} }這段代碼的核心在于第5行的RPC.getServer方法,該方法有四個參數,第一個參數是被調用的java對象,第二個參數是服務器的地址,第三個參數是服務器的端口?。獲得服務器對象后,啟動服務器。這樣,服務器就在指定端口監聽客戶端的請求。到此為止,服務器就處于監聽狀態,不停地等待客戶端請求到達。
3.4 構造RPC Client并發出請求
這里使用靜態方法getProxy或waitForProxy構造客戶端代理對象,直接通過代理對象調用遠程端的方法,具體如下所示:
public class MyClient {public static void main(String[] args) {InetSocketAddress inetSocketAddress = new InetSocketAddress(MyServer.IPAddress, MyServer.PORT);try {// 注意:這里傳入的版本號需要與代理保持一致IProxyProtocol proxy = (IProxyProtocol) RPC.waitForProxy(IProxyProtocol.class, IProxyProtocol.VERSION, inetSocketAddress,new Configuration());int result = proxy.Add(10, 25);System.out.println("10+25=" + result);RPC.stopProxy(proxy);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}以上代碼中核心在于RPC.waitForProxy(),該方法有四個參數,第一個參數是被調用的接口類,第二個是客戶端版本號,第三個是服務端地址。返回的代理對象,就是服務端對象的代理,內部就是使用java.lang.Proxy實現的。
經過以上四步,我們便利用Hadoop RPC搭建了一個非常高效的客戶機–服務器網絡模型。
3.5 查看運行結果
(1)啟動服務端,開始監聽客戶端請求
(2)啟動客戶端,開始向服務端發請求
(3)查看服務端狀態,是否被調用
SUMMARY:從上面的RPC調用中,可以看出:在客戶端調用的業務類的方法是定義在業務類的接口中的。該接口實現了VersionedProtocal接口。
(4)現在我們在命令行執行jps命令,查看輸出信息,會出現如下圖所示的:
從上圖中可以看到一個java進程,是“MyServer”,該進程正是我們剛剛運行的RPC的服務端類MyServer。因此,大家可以聯想到我們搭建Hadoop環境時,也執行過該命令用來判斷Hadoop的相關進程是否全部啟動。
SUMMARY:那么可以判斷,Hadoop啟動時產生的5個java進程也應該是RPC的服務端?! ?/p>
下面我們觀察NameNode的源代碼,如下圖所示,可以看到NameNode確實創建了RPC的服務端。
private void initialize(Configuration conf) throws IOException {......// create rpc serverInetSocketAddress dnSocketAddr = getServiceRpcServerAddress(conf);if (dnSocketAddr != null) {int serviceHandlerCount =conf.getInt(DFSConfigKeys.DFS_NAMENODE_SERVICE_HANDLER_COUNT_KEY,DFSConfigKeys.DFS_NAMENODE_SERVICE_HANDLER_COUNT_DEFAULT);this.serviceRpcServer = RPC.getServer(this, dnSocketAddr.getHostName(), dnSocketAddr.getPort(), serviceHandlerCount,false, conf, namesystem.getDelegationTokenSecretManager());this.serviceRPCAddress = this.serviceRpcServer.getListenerAddress();setRpcServiceServerAddress(conf);}this.server = RPC.getServer(this, socAddr.getHostName(),socAddr.getPort(), handlerCount, false, conf, namesystem.getDelegationTokenSecretManager());...... }?
轉載于:https://www.cnblogs.com/csguo/p/7568594.html
總結
以上是生活随笔為你收集整理的Hadoop RPC机制的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Vue的数据双向绑定和Object.de
- 下一篇: HDU 1232 - 畅通工程