Spark RPC 到底是個什麼鬼?
本文會為大家介紹Spark中的RPC通訊機制,詳細闡述“Spark RPC到底是個什麼鬼?”,閒話少敘,讓我們來進入Spark RPC的世界!
Spark RPC三劍客
Spark RPC中最為重要的三個抽象(“三劍客”)為:RpcEnv、RpcEndpoint、RpcEndpointRef,這樣做的好處有:
對上層的API來說,遮蔽了底層的具體實現,使用方便
可以透過不同的實現來完成指定的功能,方便擴充套件
促進了底層實現層的良性競爭,Spark 1.6.3中預設使用了Netty作為底層的實現,但Akka的依賴依然存在;而Spark 2.1.0中的底層實現只有Netty,這樣使用者可以方便的使用不同版本的Akka或者將來某種更好的底層實現
下面我們就結合Netty和“三劍客”來具體分析他們是如何來協同工作的。
Send a message locally
我們透過Spark原始碼中的一個Test()來分析一下傳送本地訊息的具體流程,原始碼如下(對原始碼做了一些修改):
test("send a message locally") { @volatile var message: String = null val rpcEndpointRef = env.setupEndpoint("send-locally", new RpcEndpoint { override val rpcEnv = env override def receive = { //case msg: String => message = msg case msg: String => println(message) //我們直接將接收到的訊息列印出來 } }) rpcEndpointRef.send("hello") //下面是原來的程式碼 //eventually(timeout(5 seconds), interval(10 millis)) { // assert("hello" === message) //} }
為了方便理解,先把流程圖貼出來,然後詳細進行闡述:
下面我們來詳細闡述上例的具體過程:
首先是RpcEndpoint建立並註冊的流程:(圖中的藍色線條部分)
1、建立RpcEndpoint,並初始化rpcEnv的引用(RpcEnv已經建立好,底層實際上是例項化了一個NettyRpcEnv,而NettyRpcEnv是透過工廠方法NettyRpcEnvFactory建立的)
2、例項化RpcEndpoint之後需要向RpcEnv註冊該RpcEndpoint,底層實現是向NettyRpcEnv進行註冊,而實際上是透過呼叫Dispatcher的registerRpcEndpoint方法向Dispatcher進行註冊
3、具體的註冊就是向endpoints、endpointRefs、receivers中插入記錄:而receivers中插入的資訊會被Dispatcher中的執行緒池中的執行緒執行:會將記錄take出來然後呼叫Inbox的process方法透過模式匹配的方法進行處理,註冊的時候透過匹配到OnStart型別的message,去執行RpcEndpoint的onStart方法(例如Master、Worker註冊時,就要執行各自的onStart方法),本例中未做任何操作
4、註冊完成後返回RpcEndpointRef,我們透過RpcEndpointRef就可以向其代表的RpcEndpoint傳送訊息
下面就是透過RpcEndpointRef向其代表的RpcEndpoint傳送訊息的具體流程:(圖中的紅色線條部分)
1、2、呼叫RpcEndpointRef的send方法,底層實現是呼叫Netty的NettyRpcEndpointRef的send方法,而實際上又是呼叫的NettyRpcEnv的send方法,傳送的訊息使用RequestMessage進行封裝:
nettyEnv.send(RequestMessage(nettyEnv.address, this, message))
3、4、NettyRpcEnv的send方法首先會根據RpcAddress判斷是本地還是遠端呼叫,此處是同一個RpcEnv,所以是本地呼叫,即呼叫Dispatcher的postOneWayMessage方法
5、postOneWayMessage方法內部呼叫Dispatcher的postMessage方法
6、postMessage會向具體的RpcEndpoint傳送訊息,首先透過endpointName從endpoints中獲得註冊時的EndpointData,如果不為空就執行EndpointData中Inbox的post(message)方法,向Inbox的mesages中插入一條InboxMessage,同時向receivers中插入一條記錄,此處將Inbox單獨畫出來是為了方便大家理解
7、Dispatcher中的執行緒池會拿出一條執行緒用來迴圈receivers中的訊息,首先使用take方法獲得receivers中的一條記錄,然後呼叫Inbox的process方法來執行這條記錄,而process將messages中的一條InboxMessage(第6步中插入的)拿出來進行處理,具體的處理方法就是透過模式匹配的方法,匹配到訊息的型別(此處是OneWayMessage),然後來執行RpcEndpoint中對應的receive方法,在此例中我們只列印出這條訊息(步驟8)
至此,一個簡單的傳送本地訊息的流程執行完成。
什麼,上面的圖太複雜了?我也覺得,下面給出一張簡潔的圖:
我們透過NettyRpcEndpointRef來發出一個訊息,訊息經過NettyRpcEnv、Dispatcher、Inbox的共同處理最終將訊息傳送到NettyRpcEndpoint,NettyRpcEndpoint收到訊息後進行處理(一般是透過模式匹配的方式進行不同的處理)
如果進一步的進行抽象就得到了我們剛開始所講的“三劍客”:RpcEnv、RpcEndpoint、RpcEndpointRef
RpcEndpointRef傳送訊息給RpcEnv,RpcEnv查詢註冊資訊將訊息路由到指定的RpcEndpoint,RpcEndpoint接收到訊息後進行處理(模式匹配的方式)
RpcEndpoint的宣告週期:constructor -> onStart -> receive* -> onStop
其中receive*包括receive和receiveAndReply
本文我們只是透過一個簡單的測試程式分析了Spark Rpc底層的實現,叢集中的其它通訊(比如Master和Woker的通訊)的原理和這個測試類似,只不過具體的傳送方式有所不同(包括ask、askWithRetry等),而且遠端發訊息的時候使用了OutBox和NIO等相關的內容,感興趣的朋友可以對原始碼進行詳細的閱讀,本文不一一說明,目的就是透過簡單的測試理解大致流程,不再為“Spark Rpc到底是什麼”而糾結,一句話總結:Spark Rpc就是Spark中對分散式訊息通訊系統的高度抽象。
本文為原創,歡迎轉載,轉載請註明出處、作者,謝謝!
作者:sun4lower
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2471/viewspace-2818838/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Petya到底是個什麼鬼
- pyc是個什麼鬼?
- Google、Facebook等均開始支援的HTTP3到底是個什麼鬼?GoHTTP
- 亞馬遜上的UPC,ASIN,EAN,GCID到底是什麼鬼?亞馬遜GC
- 聊聊redis單執行緒為什麼能做到高效能和io多路複用到底是個什麼鬼Redis執行緒
- Django-rest-framework 是個什麼鬼?DjangoRESTFramework
- ASP.NET Core 基於宣告的訪問控制到底是什麼鬼?ASP.NET
- UILayer是什麼鬼UI
- 《Machine Learning in Action》—— Taoye給你講講決策樹到底是支什麼“鬼”Mac
- mod_perl到底是個什麼
- Spring 5 core 中的 @NonNull 是個什麼鬼?!SpringNull
- 訊息佇列究竟是個什麼鬼?佇列
- Python 中的 sys.argv 是個什麼鬼?Python
- 什麼是rpc?RPC
- 一文帶你搞懂 RPC 到底是個啥RPC
- cross-env 是什麼鬼ROS
- where 1=1 是什麼鬼?
- SaaS,PaaS,IaaS都是什麼鬼
- “新怪談”到底是個什麼東西?
- 常用的HashMap到底是個什麼結構HashMap
- ETL到底是什麼?
- [譯] JavaScript:回撥是什麼鬼?JavaScript
- chmod 755 究竟是什麼鬼?
- [轉]DevOps究竟是什麼鬼?dev
- 來聊聊,這個Java到底是什麼東西?Java
- 圖神經網路,這到底是個什麼?神經網路
- Spring入門學習手冊 3:AOP是個什麼鬼?Spring
- 布隆過濾器是什麼鬼?有什麼用?過濾器
- Spark core篇 Rpc原始碼1SparkRPC原始碼
- Spark RPC框架原始碼分析(二)RPC執行時序SparkRPC框架原始碼
- 火了那麼久的區塊鏈,到底是個什麼玩意?區塊鏈
- Java到底是什麼呢Java
- Spring Aware 到底是什麼?Spring
- Spring IoC 到底是什麼Spring
- 理解DOM到底是什麼
- FastThreadLocal 是什麼鬼?吊打 ThreadLocal 的存在!!ASTthread
- 節流函式throttle是什麼鬼?函式
- Spark RPC框架原始碼分析(三)Spark心跳機制分析SparkRPC框架原始碼