Spark作為分布式計算框架,多個節點的設計與相互通信模式是其重要的組成部分。
一、組件概覽
對源碼分析,對於設計思路理解如下:

- RpcEndpoint:RPC端點 ,Spark針對於每個節點(Client/Master/Worker)都稱之一個Rpc端點 ,且都實現RpcEndpoint接口,內部根據不同端點的需求,設計不同的消息和不同的業務處理,如果需要發送(詢問)則調用Dispatcher
- RpcEnv:RPC上下文環境,每個Rpc端點運行時依賴的上下文環境稱之為RpcEnv
- Dispatcher:消息分發器,針對於RPC端點需要發送消息或者從遠程RPC接收到的消息,分發至對應的指令收件箱/發件箱。如果指令接收方是自己存入收件箱,如果指令接收方為非自身端點,則放入發件箱
- Inbox:指令消息收件箱,一個本地端點對應一個收件箱,Dispatcher在每次向Inbox存入消息時,都將對應EndpointData加入內部待Receiver Queue中,另外Dispatcher創建時會啟動一個單獨線程進行輪詢Receiver Queue,進行收件箱消息消費
- OutBox:指令消息發件箱,一個遠程端點對應一個發件箱,當消息放入Outbox后,緊接着將消息通過TransportClient發送出去。消息放入發件箱以及發送過程是在同一個線程中進行,這樣做的主要原因是遠程消息分為RpcOutboxMessage, OneWayOutboxMessage兩種消息,而針對於需要應答的消息直接發送且需要得到結果進行處理
- TransportClient:Netty通信客戶端,根據OutBox消息的receiver信息,請求對應遠程TransportServer
- TransportServer:Netty通信服務端,一個RPC端點一個TransportServer,接受遠程消息后調用Dispatcher分發消息至對應收發件箱
- 特別說明
-
- TransportClient與TransportServer通信虛線表示兩個RpcEnv之間的通信,圖示沒有單獨表達式
- 一個Outbox一個TransportClient,圖示沒有單獨表達式
- 一個RpcEnv中存在兩個RpcEndpoint,一個代表本身啟動的RPC端點,另外一個為 RpcEndpointVerifier
二、Endpoint啟動過程
啟動的流程如下:

- Endpoint啟動過程基本上與組件概覽中組件能很好的對應
- Endpoint啟動后,默認會向Inbox中添加OnStart消息,不同的端點(Master/Worker/Client)消費OnStart指令時,進行相關端點的啟動額外處理
- Endpoint啟動時,會默認啟動TransportServer,且啟動結束后會進行一次同步測試rpc可用性(askSync-BoundPortsRequest)
- Dispatcher作為一個分發器,內部存放了Inbox,Outbox的等相關句柄和存放了相關處理狀態數據,結構大致如下
三、Endpoint Send&Ask流程
Endpoint的消息發送與請求流程,如下:


- Endpoint根據業務需要存入兩個維度的消息組合:send/ask某個消息,receiver是自身與非自身
- OneWayMessage: send + 自身, 直接存入收件箱
- OneWayOutboxMessage:send + 非自身,存入發件箱並直接發送
- RpcMessage: ask + 自身, 直接存入收件箱,另外還需要存入LocalNettyRpcCallContext,需要回調后再返回
- RpcOutboxMessage: ask + 非自身,存入發件箱並直接發送,,需要回調后再返回
四、Endpoint receive流程
Endpoint的消息的接收,流程如下:


- 上圖 ServerBootstrap為Netty啟動服務,SocketChanel為Netty數據通道
- 上述包含TransportSever啟動與消息接受兩個流程
五、Endpoint Inbox處理流程
Spark在Endpoint的設計上核心設計即為Inbox與Outbox,其中Inbox核心要點為
- 內部的處理流程拆分為多個消息指令(InboxMessage)存放入Inbox
- 當Dispatcher啟動最后,會啟動一個名為【dispatcher-event-loop】的線程掃描Inbox待處理InboxMessage,並調用Endpoint根據InboxMessage類型做相應處理
- 當Dispatcher啟動最后,默認會向Inbox存入OnStart類型的InboxMessage,Endpoint在根據OnStart指令做相關的額外啟動工作,三端啟動后所有的工作都是對OnStart指令處理衍生出來的,因此可以說OnStart指令是相互通信的源頭
消息指令類型大致如下三類
- OnStart/OnStop
- RpcMessage/OneWayMessage
- RemoteProcessDisconnected/RemoteProcessConnected/RemoteProcessConnectionError
六,Endpoint畫像


該圖理解 Endpoint的結構使用,不再贅述。