spark2.1源碼分析4:spark-network-common模塊的設計原理

spark-network-common模塊底層使用netty作爲通訊框架,可以實現rpc消息、數據塊和數據流的傳輸。



Message類圖

這裏寫圖片描述
所有request消息都是RequestMessage的子類
所有response消息都是ResponseMessage的子類



TransportClient主要提供了三個方法:

//通過給定的streamId,獲取遠端數據流
public void stream(final String streamId, final StreamCallback callback);
//發送一份不透明的消息到遠端
public long sendRpc(ByteBuffer message, final RpcResponseCallback callback);
//通過給定的streamId,獲取遠端的數據塊
public void fetchChunk(long streamId,final int chunkIndex,final ChunkReceivedCallback callback);



Channel Pipeline:

通過TransportClientFactory的createClient方法追蹤ChannelInitializer設置,最後在TransportContext的initializePipeline方法中可以看到具體的Handler的配置:

channel.pipeline()
        .addLast("encoder", encoder)  
        .addLast(TransportFrameDecoder.HANDLER_NAME, NettyUtils.createFrameDecoder())  
        .addLast("decoder", decoder)
        .addLast("idleStateHandler", new IdleStateHandler(0, 0, conf.connectionTimeoutMs() / 1000))
        .addLast("handler", channelHandler);

此處得到的handler鏈爲:

MessageEncoder-->TransportFrameDecoder-->MessageDecoder-->IdleStateHandler-->TransportChannelHandler

MessageEncoder:負責將消息轉換爲netty框架中的ByteBuf
MessageDecoder:負責網絡傳輸的的ByteBuf轉換爲具體的消息
TransportFrameDecoder:負責接收網絡傳輸的ByteBuf,解析爲一個指定大小的ByteBuf交予MessageDecoder,或者交給StreamInterceptor處理
IdleStateHandler:心跳檢測
TransportChannelHandler:負責消息的具體處理



發送端發送消息的流程:

  1. 通過TransportClient的實例發送RequestMessage消息
  2. MessageEncoder把消息轉換爲ByteBuf
    所有RequestMessage的子類都繼承了AbstractMessage,而AbstractMessage有一個叫body的filed,該字段在RpcRequest中被用來存儲具體的請求內容(不止RpcRequest)。當body爲空時該消息直接轉換爲ByteBuf;不爲null時,MessageEncoder將消息轉換爲MessageWithHeader,MessageWithHeader繼承了AbstractReferenceCounted ,實現了FileRegion ,最後消息仍會轉換爲ByteBuf。注意:MessageWithHeader提供了發送文件的能力。

    MessageWithHeader類:
    class MessageWithHeader extends AbstractReferenceCounted implements FileRegion

  3. ByteBuf被髮送到網絡(ByteBuf中包含這個消息的總長度、字段長度、具體內容等信息)



接收端接收消息並響應:

  1. TransportFrameDecoder負責拼接一個RequestMessage所需的完整ByteBuf
  2. MessageDecoder將消息解析爲一個RequestMessage消息
  3. TransportChannelHandler將消息交給TransportRequestHandler具體處理
  4. TransportRequestHandler將ResponseMessage消息傳遞給MessageEncoder
  5. MessageEncoder把消息轉換爲ByteBuf(同上)



發送端接收響應消息:

  1. TransportFrameDecoder負責拼接一個消息所需的完整ByteBuf,如果是StreamResponse消息並且body是一個FileRegion,那麼先拼接這個消息的ByteBuf(注意:StreamResponse消息最終傳輸到網絡上時本身不包含FileRegion的ByteBuf)
  2. MessageDecoder將消息解析爲一個ResponseMessage消息
  3. TransportChannelHandler將消息交給TransportResponseHandler具體處理
  4. 如果StreamResponse是一個包含FileRegion的消息,TransportResponseHandler在Channel Pipeline中添加一個handler:StreamInterceptor。TransportFrameDecoder將使用StreamInterceptor處理後續的FileRegion的ByteBuf。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章