Autodesk基于Mesos和Kafka的通用事件系統架構

jopen 9年前發布 | 18K 次閱讀 Autodesk

我非常喜歡這篇博客,因為它揭示了許多簡單架構模塊—例如:Mesos、Kafka、RabbitMQ、Akka、Splunk、Librato和EC2可以整合起來來解決實際問題。而且一個小團隊就可以獲得非常令人驚訝的成就。

幾個月前我被分配一個新任務,要求拿出一個集中事件系統的解決方案,這個系統可以允許各種后端彼此通訊。這些后端包括動態消息、渲染、數據轉換、 BIM、身份驗證、日志報告、分析等等后端應用。這應該是一個可以適配多種應用、使用場景與可擴展配置文件的通用系統。當然,這個系統還應該有易用的接 口,以及動態擴展性。

顯然我不可能有時間寫很多代碼。因為Kafka可以動態擴展,在業內被廣泛應用,所以選擇它作為核心存儲方案(請注意不一定非要使用 Kafka)。現在我當然不能直接把它發布,而是通過一些API對前端提供服務。如果不深思熟慮,我也拒絕讓后端處理偏移量(offsets),因為這會 對如何應對實例失效造成太多限制。

那我該怎么辦呢?兩個獨立的分層:第一是處理訪問流量的API層,然后是保持長期鏈接和有狀態消息流進程的后臺層,后臺層和Kafka通信(也就是說,完成生產者和消費者的角色)。每一層都各自獨立擴展,只需要一致性路由來保證客戶端持續跟同一個后臺消息流進程溝通。

這兩層都是100%使用Scala語言開發的 Play!框 架,而且嚴重依賴Akka Actor系統(每個節點都運行幾百個Actor)。后臺層部署了一系列客制化的Kafka消息生產者和消費者,用一系列指定的actors來處理預讀和 寫緩沖,所有服務都以內置的有限狀態機(我喜歡這個概念)方式部署,數據搜集由Librato完成(實際上是運行在容器內的collectd),而分析由 Splunk完成。

 Autodesk基于Mesos和Kafka的通用事件系統架構

手繪圖:發布流程圖

那么,這兩層直接如何路由呢?可以使用RabbitMQ來實現就好了,它可以提供足夠的容錯性和一致性。AMQP隊列可以很好地實現“電話交換 機”模式,縱向擴展就不用說了,同時可以使用某些邏輯分區(例如通過hash分配到代表每個交易的cookie上或者類似的特征上),是的一部分固定的后 端節點與一個RabbitMQ代理聯系起來。

為什么我不對RabbitMQ代理采用集群模式呢?嗯,主要是因為我比較懶而且這也不是必須的。在我看來,每個代理之間的分區流量既有效又容易控制,跟好處比起來額外工作量可以認為忽略不計。

因此簡要來說,考慮到不同后臺節點運行不同消息流, 因此我們需要的容器技術會繼續使用特定的路徑。擴展整個架構就跟互不影響擴展每一層任務一樣微不足道,唯一實際限制來自于虛擬網卡和帶寬。

 Autodesk基于Mesos和Kafka的通用事件系統架構

虛線代表某一個特定session持續使用的通道

接下來就是比較有趣的部分:我們如何確保可信交易以及避免錯綜復雜的失效。要我來說,這個更加容易,只需要一個簡單的雙向握手(2-phase commit-esque protocol and mode) 協議和模式,這樣你的客戶端和背景作為鏡像狀態機處于完全同步狀態。可以通過給讀寫操作請求返回一個明確的請求響應方式來實現。當需要讀取的時候,如果失 敗就一直重試知道得到一個響應,然后轉變為后臺服務響應(例如,轉發kafka offset,或者預約發布事件)。這樣客戶端和后臺之間的交互流量就真的像“分配一個session”,“讀”,“應答響應”,“讀”,“應答響 應”........“部署”。

通過這些處理,系統的巨大優勢在于可以有效地呈現操作冪等,同時還可以在狀態機上編譯所有邏輯,無需使用煩人的說明語句。此外,任何網絡失效當然會重試,也順便會從中獲得免費的控制流和背壓路由(back-pressure routing)。

這樣所有的服務對外就表現為一個Apache Thrift的API(現在通過帶壓縮HTTPS加密隧道,將在未來某個時間計劃改為明碼TCP)。我有使用Python、Scala、.Net和 Ruby的SDK客戶端來使用這些令人目眩的新技術。請注意盡管Kafka偏移被客戶端管理(盡管這樣不透明),但是這樣可以使得后端變的更加簡單且容易 控制。

等一下,當后端節點失效怎么來處置呢?因為有了雙向握手協議,因此當讀數據時,這并不會成為問題:當后端節點失效時,客戶端持續得到失敗返回,接 下里就會使用現在的偏移量重新申請一個鏈接。如果向Kafka寫入數據時,因為這是異步過程,而且可能會出現雙向失效(例如客戶端和Kafka代理節點同 時有問題),因此有可能會出現問題。為了解決寫問題,當有等待任何等待寫操作完成時,后臺節點會對任何其它訪問請求返回失敗,或者在最近的可恢復點將任何 掛起數據刷新入磁盤(之后在重新讀入)。

那么當部分架構出現問題怎么處理呢?同樣的解決辦法。任何客戶端和后臺節點之間的中斷鏈接會影響到鏈接的響應速度,但是因為有雙向握手協議,并不會有任何嚴重的問題。

哦,我忘了提到數據寫入Kafka日志之前數據都會自動(AES256)加密,而在Kafka消息生產者和消費者之間共享秘鑰是不可能的。從安全角度來看,流鏈接是通過OAUTH2認證的,每個連接使用單獨的MD5-HMAC認證,并通過TLS在后端集群之間傳輸。

那么,你現在會問到底是怎么部署這套酷斃的系統呢?我們100%部署這套系統是通過標準的Mesos、Marathon集群來部署的(現在還不是 DCOS,但是我們很有可能會轉向它,并從炫酷的儀表盤受益)。集群目前都是運行在AWS的EC2上,我們一般會在多個c3.2xlarge實例上被復用 (在給定區域中執行一個小型部署,10到20算不少了)。請注意,在Kubernetes(不管是EC2還是GCE)也可以使用同樣的方法。

 Autodesk基于Mesos和Kafka的通用事件系統架構

我們集群運行的一個簡單架構示意圖

我們使用Ochopod技術完成部署(自集群容器),它同樣是開源的,可以將交互操作減到最少。比如將一次構建推入API層時,此系統只負責分配 一些新的容器,等分配好之后再逐步清理舊的。所有這些操作都通過一個專門的、在集群中運行的Jenkins從節點來處理(其本身也是一個Ochopod容 器)。

事實上,我也開發了Ochothon mini-PaaS,只是為了快速開發運維(devops)所有的容器。

 Autodesk基于Mesos和Kafka的通用事件系統架構

Ochothon 命令行展示我們一套預配置的集群

這些Ocho-*平臺到底能起到多大作用呢?可以說一個人(比如我)可以管理管理跨越兩個區域管理五套這樣的系統部署,包括備份架構。而且同時我還有時間來記錄下這些博客和代碼。

總體上來說,設計和編碼實現這樣的系統有很多樂趣,而且它現在作為云基礎架構的關鍵部分支撐著我們的生產環境。如果想了解關于這套迷人系統更多的內容,可以聯系我們。

相關文章

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!