Hadoop的IPC: (1)實現(xiàn)RPC的一種方法,具有快速、簡單的特點。 它不像Sun公司提供的標準RPC包,基于Java序列化。 (2)IPC無需創(chuàng)建網(wǎng)絡(luò)stubs和skeletons。 (3)IPC中的方法調(diào)用要求參數(shù)和返回值的數(shù)據(jù)類型必須是Java的基本類型,String和Writable接口的實現(xiàn)類,以及元素為以上類型的數(shù)組。接口方法應該只拋出IOException異常。
構(gòu)建思路:(1)采用客戶/服務(wù)器模型 (2)Server:它把Java接口暴露給客戶端。指定好監(jiān)聽端口和接受遠程調(diào)用的對象實例后,通過RPC.getServer()可以得到Server實例。 (3)Client:連接Server,調(diào)用它所暴露的方法。Client必須指定遠程機器的地址,端口和Java接口類,通過RPC.getClient()可以得到Client實例。 (4)Server不可以向Client發(fā)出調(diào)用,但在Hadoop中,有雙向調(diào)用的需求。 比如在DFS,NameNode和DataNode需要互相了解狀態(tài)。 詳細設(shè)計: (1)Writable接口,實現(xiàn)此接口的類可以把類中的域放入流中以及從流中讀數(shù)據(jù)到域中。 (2)對象在傳遞時按照:對象類名+對象類名長度+對象序列化數(shù)據(jù),的格式傳輸,需要一個類可以解析這種格式,這個類是ObjectWritable,這個類需要知道所有實現(xiàn)Writable的類,以便可以通過類名生成新的對象,故此類依賴于WritableFactories,那存儲了Writable子類對應的工廠。 (3)Client類用來和Server通信,一個Client可以發(fā)起多個連接,連接需要標識,使用Client.ConnectionId(包含InetSocketAddress,UserGroupInformation,Class<?>)。每個連接有多個調(diào)用,使用Client.Call標識(包含int<id>,Writable<param,value>,IOException,boolean<done>)。每個連接用Hashtable<Integer, Call>保存發(fā)起的調(diào)用。 (4)RPC是Server和Client的結(jié)合,waitForProxy方法用來返回一個所有可以采用這種IPC調(diào)用的所有接口的父接口VersionedProtocol,其他不同的接口繼承這個父接口,這些接口需要有一個版本號。waitForProxy方法的參數(shù)應該有用戶想要調(diào)用方法的接口類<Class>,遠程調(diào)用的地址<InetAddress>等等。waitForProxy方法返回的是一個動態(tài)代理,真正完成方法遠程調(diào)用的是RPC.Invoker因為,它實現(xiàn)了InvocationHandler接口。 (5)Invoker主要從緩存中取一個Client出來,然后調(diào)用Client.call方法,這個方法需要知道方法名,方法參數(shù),方法聲明類以及遠端地址。 (6)Client.call方法需要根據(jù)ConnectionId從緩存中獲得Connection,或者新建立一個Connection。Connection的sendParam方法供調(diào)用call的線程發(fā)送調(diào)用參數(shù)(方法名,方法參數(shù),方法聲明類),在調(diào)用sendParam之前,Connection已經(jīng)建立好連接并發(fā)送ConnectionHeader,之后立刻啟動接受線程,接受到的可能是函數(shù)調(diào)用的結(jié)果,也可能是連接上的異常消息。 (7)Server的Listen線程負責監(jiān)聽新連接并把讀取的調(diào)用參數(shù)放入BlockingQueue隊列,Handler線程負責從隊列中拿出Call對象進行處理。
(8)Hadoop的IPC框架做得很好,接下來準備仿照實現(xiàn)一個,更好的發(fā)現(xiàn)這個框架的實現(xiàn)技巧。 |
|