本文講的是<b>Autodesk基于Mesos和Kafka的通用事件系統架構</b>,【編者的話】我非常喜歡這篇部落格,因為它揭示了許多簡單架構子產品—例如:Mesos、Kafka、RabbitMQ、Akka、Splunk、Librato和EC2可以整合起來來解決實際問題。而且一個小團隊就可以獲得非常令人驚訝的成就。
幾個月前我被配置設定一個新任務,要求拿出一個集中事件系統的解決方案,這個系統可以允許各種後端彼此通訊。這些後端包括動态消息、渲染、資料轉換、BIM、身份驗證、日志報告、分析等等後端應用。這應該是一個可以适配多種應用、使用場景與可擴充配置檔案的通用系統。當然,這個系統還應該有易用的接口,以及動态擴充性。
顯然我不可能有時間寫很多代碼。因為Kafka可以動态擴充,在業内被廣泛應用,是以選擇它作為核心存儲方案(請注意不一定非要使用Kafka)。現在我當然不能直接把它釋出,而是通過一些API對前端提供服務。如果不深思熟慮,我也拒絕讓後端處理偏移量(offsets),因為這會對如何應對執行個體失效造成太多限制。
那我該怎麼辦呢?兩個獨立的分層:第一是處理通路流量的API層,然後是保持長期連結和有狀态消息流程序的背景層,背景層和Kafka通信(也就是說,完成生産者和消費者的角色)。每一層都各自獨立擴充,隻需要一緻性路由來保證用戶端持續跟同一個背景消息流程序溝通。

手繪圖:釋出流程圖
那麼,這兩層直接如何路由呢?可以使用RabbitMQ來實作就好了,它可以提供足夠的容錯性和一緻性。AMQP隊列可以很好地實作“電話交換機”模式,縱向擴充就不用說了,同時可以使用某些邏輯分區(例如通過hash配置設定到代表每個交易的cookie上或者類似的特征上),是的一部分固定的後端節點與一個RabbitMQ代理聯系起來。
為什麼我不對RabbitMQ代理采用叢集模式呢?嗯,主要是因為我比較懶而且這也不是必須的。在我看來,每個代理之間的分區流量既有效又容易控制,跟好處比起來額外工作量可以認為忽略不計。
是以簡要來說,考慮到不同背景節點運作不同消息流, 是以我們需要的容器技術會繼續使用特定的路徑。擴充整個架構就跟互不影響擴充每一層任務一樣微不足道,唯一實際限制來自于虛拟網卡和帶寬。
虛線代表某一個特定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)也可以使用同樣的方法。
我們叢集運作的一個簡單架構示意圖
我們使用Ochopod技術完成部署(自叢集容器),它同樣是開源的,可以将互動操作減到最少。比如将一次建構推入API層時,此系統隻負責配置設定一些新的容器,等配置設定好之後再逐漸清理舊的。所有這些操作都通過一個專門的、在叢集中運作的Jenkins從節點來處理(其本身也是一個Ochopod容器)。
事實上,我也開發了Ochothon mini-PaaS,隻是為了快速開發運維(devops)所有的容器。
Ochothon 指令行展示我們一套預配置的叢集
這些Ocho-*平台到底能起到多大作用呢?可以說一個人(比如我)可以管理管理跨越兩個區域管理五套這樣的系統部署,包括備份架構。而且同時我還有時間來記錄下這些部落格和代碼。
總體上來說,設計和編碼實作這樣的系統有很多樂趣,而且它現在作為雲基礎架構的關鍵部分支撐着我們的生産環境。如果想了解關于這套迷人系統更多的内容,可以聯系我們。
<a href="http://cloudengineering.autodesk.com/blog/2015/05/after-a-long-day-of-devops-to-inaugurate-the-latest-ochothon-release-i-though-id-share-quick-what-it-feels-like-deploying-ou.html">Deploying our eventing infrastructure over Mesos/Marathon & Ochothon !</a>
<a href="http://cloudengineering.autodesk.com/blog/2015/05/ochopod_plus_kubernetes.html">Ochopod + Kubernetes = Ochonetes</a>
<a href="http://cloudengineering.autodesk.com/blog/2015/07/fsm.html">Return of the finite state machine!</a>
原文釋出時間為:2015-08-22
本文作者:giam
本文來自雲栖社群合作夥伴DockerOne,了解相關資訊可以關注DockerOne。
原文标題:Autodesk基于Mesos和Kafka的通用事件系統架構