最近開始看Hadoop的一些源碼,展開hadoop的源碼包,各個組件分得比較清楚,于是開始看一下IPC的一些源碼。(版本是1.0.4中的ipc包)
IPC模塊,也就是進程間通信模塊,如果是在不同的機器上,那就可以理解為RPC了,也就是遠程調(diào)用。事實上,hadoop中的IPC也就是基于RPC實現(xiàn)的。
使用sloccount統(tǒng)計一下ipc包中代碼的行數(shù),一共是2884行。也就是說,IPC作為hadoop的基礎(chǔ)組件,僅僅用了不到3000行的代碼,就完成得穩(wěn)定且富有效率。
IPC中的關(guān)鍵類關(guān)系:

對用戶而言,可以直接使用的就是綠色的類。
通過RPC這個門面:
- 客戶端可以創(chuàng)建相應(yīng)的proxy,接著就可以進行遠程調(diào)用。
- 而服務(wù)提供者則可以創(chuàng)建相應(yīng)的server,并進行相應(yīng)的生命周期管理(start、stop),從而提供服務(wù)。
序列化
從上圖也可以看出,client和server的交互,是通過網(wǎng)絡(luò)connection,而走網(wǎng)絡(luò)的調(diào)用,是需要走序列化/反序列話的過程的。
這個過程,IPC使用了Hadoop的自己的序列化機制,一切都在Writable接口中,只要給定writable的DataOutput和DataInput,就可以讓W(xué)ritable自己實現(xiàn)序列化。
一些問題和思考
- client是單例的嗎——可以理解為是,但其實不一定??梢愿檊etProxy的代碼,雖然每次都會新建一個代理對象,但底層的Client還是和SocketFactory對應(yīng)的。一般默認的,都是使用默認的SocketFactory,但如果你設(shè)置了”hadoop.rpc.socket.factory.class.default”,則會有新的Client與你自定義的SocketFactory對應(yīng)。這時候,client就不是單例的。
- client與同一個server有幾個連接——一個client與一個server只有一個連接,具體可以看生成的代理中,有一個remoteId,這個remoteId是和client關(guān)聯(lián)的,client進行調(diào)用的使用,會將此remoteId作為一個connectionId。因此,一般一個client是一個連接。
- 如果client是一個連接,那么對此client的調(diào)用,不都是串行的嗎?——看你怎么理解了,在用戶層面,也就是client調(diào)用的方法,是可以并發(fā)的。client底層是使用一個連接來進可能的完成吞吐量。每個request和response都會有一個id關(guān)聯(lián)起來。因此一個連接上可以跑滿請求和相應(yīng)。
- 由于網(wǎng)絡(luò)問題,client調(diào)用服務(wù)失敗后,有重試機制嗎——在IPC中沒有看到call的重試,需要上層去保證了。但是后面的調(diào)用會重新建立連接。
- server是單例的嗎——不一定。如果你只getServer一次的話。創(chuàng)建一個server的代價是非常重的。通過上圖你也可以知道,他需要有一個線程(Listener)來acceptsocket,同時需要一些Reader線程來進行socket的read,還有一個Responder來進行socket的write,另外,還有若干個handler線程來進行業(yè)務(wù)處理。因此,如果可以減少server的個數(shù),就應(yīng)該減少server個數(shù)。
- 暴露出的服務(wù)是否應(yīng)該是線程安全的——是的,一定要線程安全。server底層是通過nio進行socket操作的,因此雖然只有一個線程負責(zé)accept,但是能夠支持很多的client連接。這些連接在到達server端之后,很有可能就會并發(fā)執(zhí)行同一方法(如果你的業(yè)務(wù)handler不止一個的話)
- 一個server要消耗多少線程資源?——讓我們來算一下,一個Listener線程,若干個Reader線程(默認1個),若干個Handler線程(在getServer的時候指定,一般1-10個),一個Responder線程。如果都按照默認值來計算的話。最少需要1+1+1+1=4個線程。也許,不應(yīng)該算多,如果請求量不大的話,這些線程應(yīng)該都被blocked住的。
總結(jié)
- Hadoop的IPC是一個比較輕量級別的RPC
- 從代碼來看,只支持java進程之間的通信
- 從沒有重試機制、一個Client只有一個連接的機制來看,適合與應(yīng)用網(wǎng)絡(luò)環(huán)境較好的場景,適合同機架或者同機房的集群。
P.S.看了一下io包中,其實有個retry的package,里面就是一個重試機制。奇怪的是為啥這個package被包含在iopackage中。
VIA:zavakid
更多詳細信息,請您微信關(guān)注“計算網(wǎng)”公眾號: