Twitter Storm源代碼分析之DRPC架構細節
發表于 2012 年 02 月 24 日 由 xumingming 作者: xumingming | 可以轉載, 但必須以超連結形式标明文章原始出處和作者資訊及版權聲明
網址: http://xumingming.sinaapp.com/765/twitter-storm-code-analysis-drpc-arch/
概述
在前一篇文章中我們介紹了Storm DRPC是怎麼利用Storm提供的Tuple, Spout, Bolt, Topology這些原語封裝出來的,可以說确實很精妙,那篇文章的重點是如何利用原語來實作DRPC的功能。這篇文章我們來看一看整個Storm DRPC的架構,整個DRPC裡面參與的各方如何互動消息而組成這樣一個系統。
架構解析
有圖有真相, 我們先看看DRPC的架構圖:

從上面的圖中看,整個DRPC分為了3個部分:
- Client: 真正使用DRPC服務的代碼
- DRPCServer: 從Client角度來看的DRPC伺服器,就是它把DRPC所有的實作細節從Client的眼中隐藏了。
- Storm: 這裡的Storm是指真正實作DRPC功能的storm的Spout, Bolt, 比如JoinResult,ReturnResults等等。
這裡比較有意思的一點是對于DRPCServer來說,Client和Storm都是“用戶端”,隻是幹的工作不同,我們下面通過來分析下整個請求送出,傳回的流程來看看它們各自都幹了啥:
- 首先
送出請求給DRPCClient
DRPCServer
-
首先給這個請求産生一個DRPCServer
, 然後把它丢到一個request-id
池子裡面request-id -> request
-
在把request放入池子裡面的時候,會同時生成一個Semaphore, 并且把這個Semaphore把放到一個DRPCServer
池子裡面去request-id -> semaphore
- 同時它調用
來等在這個semaphore.acquire()
上面等待結果的到來。semaphore
-
- Storm元件從
池子中擷取需要處理的請求request-id -> request
- 通過DRPCSpout, PreapreRequest, JoinResult, ReturnResults一幫家夥去處理這個請求。
- 把處理完的請求結果發回到DRPCServer的
池子裡面去。request-id -> result
- 同時會通過
去request-id
池子裡面取出這個請求所對應的semaphore, 并且調用request-id -> semaphore
來釋放這個semaphore.release()
semaphore
- 同時會通過
-
被釋放之後,DRPCServer上面阻塞的等待線程得以繼續執行,去semaphore
池子裡面把結果取出來,傳回給等待的用戶端。request-id -> result
異步DRPC
Storm現在還不支援異步的DRPC, 不過要在上面的模型的基礎上去實作異步的DRPC應該是很簡單的,我畫了一下大緻是這樣的:
和上面的同步DRPC相比改動很小:
- 請求送出之後,伺服器不會等在
上, 而是立即傳回給用戶端一個Future對象。Semaphore
- 這個
對象帶了Future
的資訊request-id
- 這個
- 在Client端維護一個
的池子, 用戶端将來調用request-id -> result
的時候就是要到這個池子裡面來找結果future.get()
- 伺服器端發現請求的結果來了之後把回用戶端的結果池子裡面去