使用Docker、Luigi和Spot Instances玩轉PB級的數據管道處理任務
數據驅動類的產品近來很火,容器技術也是正值當年,試看AdRoll公司是如何將二者結合,并充分利用容器技術的優勢,提升研發效率的。AdRoll業務模式很有前途,是關于 再定位廣告產品的,能夠最大化的提升廣告投放效果。當然其中有意思的還有 Luigi的引入解決了作業間復雜相互依賴的問題。同時很好的利用到了AWS的 Spot Instances, CloudWatch及 Auto-Scaling Groups,在最小成本下做到了彈性擴縮容,值得了解學習。
這是我們依托 Docker容器來構建數據密集型產品 AdRoll Prospecting系列文章中的第一篇。 PPT。
一個數據驅動產品
就在6月17號,我們的一款新產品 AdRoll Prospecting,發布了公網測試版。了不起的是,該產品是由一個六人小組,在六個月時間內,從頭開發并且按時發布的。該產品所做的實際上是市場營銷的圣杯: AdRoll Prospecting的核心是 一種大規模機器學習模型,通過對數十億Cookie進行分析,能夠預測出誰最有可能對您的產品感興趣,從而為您的企業發現新客戶。
現代化的數據驅動產品 AdRoll Prospecting,不單單是機器學習,還提供一個易用的儀表盤(基于 React.js構建),讓您能夠詳細查看分析的效果。在幕后,我們連接了AdRoll的 實時競價引擎,還有許多檢查點和儀表盤用以監控產品內部的健康情況,這使得我們能夠在問題影響客戶之前就將其解決。
借助于AdRoll之前開發 再定位廣告產品的經驗,我們在如何構建一種復雜系統上取得了共識。當我們著手開始 AdRoll Prospecting產品之時,我們回顧已有的經驗教訓,在不犧牲健壯性和成本前提下,如何對此類大規模數據驅動產品盡快建立一個靈活的并可持續發展的后端基礎架構。
管理復雜度
我們對結果非常滿意,這也促成了本系列文章。它不僅使我們的開發和發布按時完成,而且我們也計劃將現有工作負荷遷移到新系統。新架構最重要的功能是簡單。知曉了我們誠待解決的問題是如此復雜,我們不想引入框架使其更加復雜,并迫使我們在此框架中工作。
我們的架構是基于三個互補層所構成的一個Stack,依賴于眾所周知并身經百戰的組件:
- 在底層,我們使用AWS的Spot Instances和Auto-Scaling Groups來按需提供計算資源。數據存儲在AWS的簡單存儲服務S3中。我們建立了一個簡單內部工作隊列,Quentin,所以可依據工作隊列的實際長度,利用自定義的CloudWatch指標觸發擴縮容。
- 在中間層,我們使用Luigi來編排一套由相互依賴的批量作業組成的復雜關系圖,Luigi是基于Python的開源工作流管理工具。
- 在最上層,每個獨立任務(批量作業)均被打包成一個Docker容器。 </ol>
- 作業打包 – 一個作業可能依賴于眾多的第三方庫,而這些庫也有自己的依賴包。特別是,如果作業是腳本語言如Python或R編寫的,封裝整個環境在一個獨立包中的意義非凡。
- 作業部署 – 打包好的作業需要在主機上部署,且需要在不改變系統資源情況下被順暢地執行。
- 資源隔離 – 如果多個作業在同一主機上被同時執行,它們必須共享資源且不能相互干擾。 </ol>
上述Stack允許任何人使用 Docker快速構建新任務,根據輸入和輸出使用 Luigi定義任務間依賴關系,并使任務可在任意數量的EC2實例上執行,而無須考慮服務供應(這要感謝我們的調度和自動擴縮容組),如下圖所示。
這一簡單的架構使大量復雜性可被很好的管理起來。 Docker容器封裝了用7種不同語言實現的批量作業。Luigi用來編排約50種作業緊密相連的關系圖,Quentin和 Auto-Scaling Groups(自動擴縮容組)技術,允許我們在彈性的數百臺大規模EC2 Spot Instances實例上,以最為經濟的方式執行作業。
擁抱這一錯綜復雜、 集市化方式的最大好處是我們可以安全的為每個任務選用最適合的語言,實例類型和分布式模式。
舊新范式
將批量作業容器化已經使用了幾十年。早在上世紀60年代,在大型機上就已率先使用批量作業和虛擬化技術了。此外在本世紀初,谷歌使用操作系統級的虛擬化技術(谷歌內部系統 Borg)隔離批量作業。若干年后,使用開源軟件如 OpenVZ和 LXC,這種方法廣泛流行起來,后來又有了管理服務,例如基于 Solaris Zones的 Joyent Manta。容器技術解決了批處理中的三個棘手問題,即:
在 Docker出現之前,這些問題使用已有的虛擬化技術都可以解決,且有幾十年了。什么原因 Docker如此成功? Docker的出現使得創建容器非常容易并被大眾接受,現在每個分析師,數據科學家,初級軟件工程師都可以使用筆記本電腦在容器里打包他們的程序。
這樣做的結果是,我們可以允許并鼓勵每個系統用戶使用他們最喜愛的,最適合的工具完成作業,而不必學習一種新語言或是MapReduce等計算模型,怎么高效怎么來。每個人自然也就對他們使用 Docker打包的作業負責,出了問題也在容器內進行修復。
其結果不僅是更快的上市時間(這要感謝使用不同技能和實戰工具如R語言帶來的高效性),也是跨組織賦權的感覺。每個人都可以訪問數據,測試新的模型,并使用他們所知道的最好的工具發布代碼到生產環境。
良好行為的預期
將批量作業容器化不僅是關于和平,愛,和持續集成與部署。我們希望作業能夠遵循一定的規則。大多數作業遵循的基本模式是,作業只能從S3中獲取不可變數據作為輸入,產生不可變數據存入S3中作為輸出。如作業堅持這一簡單模式,那此類作業就是冪等的。
實際上,從函數式編程角度上來說,每個容器就是一個函數。在這一思路下,我們發現,從最簡單的Shell腳本到最復雜的數據處理作業,很自然的就寫好了容器化的批量作業。
另一相關要求是作業必須是原子的。我們期望,如同Hadoop一樣,作業在成功完成后,產生一個_SUCCESS文件。在S3中對單一文件的操作是原子的,所以這一要求很容易滿足。我們的任務依賴關系是由 Luigi建立的,只有當成功文件存在時,輸出數據才被視為有效,因而部分結果并非問題。
我們發現這一明確依賴S3中的文件方式,容易解釋、問題定位和故障排除。S3是一個近乎完美的數據結構:它高度可擴展,運行時間有著驚人的記錄,且廉價易用。如果數據不容易被訪問,則 Docker帶來的便捷性將大打折扣。
下一步:Luigi
容器化批量作業得益于關注點的明確劃分。這不僅使得作業編寫變得容易了,而且也明確了每一作業執行時間長短,是幾分鐘還是最多幾小時,對于利用瞬時計算服務 Spot Instances來說意義重大。一個不可避免的結果是,系統變成了一個作業間相互依賴的復雜毛團。 Luigi已被證明是管理這一依賴關系圖的最直接的方式,我們將在下一篇博客中探討這一主題。
原文鏈接:Petabyte-Scale Data Pipelines with Docker, Luigi and Elastic Spot Instances
===================================================
譯者介紹
Andrew,PPTV總監,樂于分享對于云計算的一些想法和對未來科技的猜想。
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!