阿里雙11超級工程:PB級文件分發重器蜻蜓

有圖有介紹見: http://tech.it168.com/a2017/1114/3179/000003179630.shtmlhtml

蜻蜓開源地址:https://github.com/alibaba/dragonflynode

2017天貓雙11, 交易峯值32.5萬/秒,支付峯值25.6萬/秒,數據庫處理峯值4200萬次/秒,成交額1682億數字的背後是50+神祕技術!其中,阿里集團基礎設施蜻蜓,在雙11期間,對上萬臺服務器同時下發5GB的數據文件,讓大規模文件分發靠蜻蜓系統完美渡過。git

 

蜻蜓,經過解決大規模文件下載以及跨網絡隔離等場景下各類難題,大幅提升數據預熱、大規模容器鏡像分發等業務能力。月均分發次數突破20億次,分發數據量3.4PB。其中容器鏡像分發比natvie方式提速可高達57倍,registry網絡出口流量下降99.5%以上。今天,阿里巴巴集團基礎架構事業羣運維中臺負責人,親歷者如柏,將爲咱們詳述蜻蜓從文件分發到鏡像傳輸的技術之路。github

 

 

毛茂德(如柏)  阿里巴巴集團基礎架構事業羣運維中臺負責人算法

 

做者簡介:毛茂德(花名:如柏):阿里巴巴集團基礎架構事業羣運維中臺負責人,親歷者。主導架構設計高可靠、高併發、大規模的基礎運維平臺和應用運維平臺, 十餘年來堅持不懈的追求研發、測試、運維效率提高,推進DevOps實施落地。目前正致力於打造基於混合雲的應用運維無人值守解決方案以及自動化、數據化、智能化應用運維解決方案。曾任職於IONA,RedHat,eBay,也是 Apache 頂級項目CXF 初創成員之一。docker

 

問題的起源數據庫

蜻蜓是阿里自研的P2P文件分發系統,是阿里基礎運維平臺重要組成部分,是雲效-智能運維平臺的核心競爭力,也是阿里雲容器服務的關鍵組件。json

 

蜻蜓的誕生倒是要從15年開始講起了。ubuntu

 

隨着阿里業務爆炸式增加,15年時發佈系統日均的發佈量突破兩萬,不少應用的規模開始破萬,發佈失敗率開始增高,而根因就是發佈過程須要大量的文件拉取,文件服務器扛不住大量的請求,固然很容易想到服務器擴容,但是擴容後又發現後端存儲成爲瓶頸。此外, 大量來自不一樣IDC的客戶端請求消耗了巨大的網絡帶寬,形成網絡擁堵。後端

 

同時,不少業務走向國際化,大量的應用部署在海外,海外服務器下載要回源國內,浪費了大量的國際帶寬,並且還很慢;若是傳輸大文件,網絡環境差,失敗的話又得重來一遍,效率極低。

 

因而很天然的就想到了P2P技術,由於P2P技術並不新鮮, 當時也調研了不少國內外的系統,可是調研的結論是這些系統的規模和穩定性都沒法達到咱們的指望。因此就有了蜻蜓這個產品。

設計目標

 

針對這些痛點,蜻蜓在設計之初定了幾個目標:

 

1.    解決文件源被打爆的問題,在Host之間組P2P網,緩解文件服務器壓力,節約跨IDC之間的網絡帶寬資源。

2.    加速文件分發速度,而且保證上萬服務器同時下載跟一臺服務器下載沒有太大的波動。

3.    解決跨國下載加速和帶寬節約。

4.    解決大文件下載問題,同時必需要支持斷點續傳。

5.    Host上的磁盤IO,網絡IO必須能夠被控制,以免對業務形成影響

系統架構

 

▲圖1. 蜻蜓總體架構

 

總體架構分三層,第一層是Config Service, 他管理全部的Cluster Manager,Cluster Manager又管理全部的Host, Host就是終端,dfget就是相似wget同樣的一個客戶端程序。

 

Config Service 主要負責Cluster Manager的管理、客戶端節點路由、系統配置管理以及預熱服務等等。簡單的說,就是負責告訴Host,離他最近的一組Cluster Manager的地址列表,並按期維護和更新這份列表,使的Host老是能找到離他最近的Cluster Manager。

 

Cluster Manager 主要的職責有兩個:1、以被動CDN方式從文件源下載文件並生成一組種子分塊數據;2、構造P2P網絡並調度每一個peer之間互傳指定的分塊數據。

 

Host上就存放着dfget,dfget的語法跟wget很是相似。主要功能包括文件下載和P2P共享等。

 

在阿里內部咱們能夠用StarAgent來下發dfget指令讓一組機器同時下載文件,在某種場景下一組機器可能就是阿里全部的服務器。因此使用起來很是高效。除了客戶端外, 蜻蜓還有Java SDK,可讓你將文件「PUSH」到一組服務器上。

 

下面這個圖闡述了兩個終端同時調用dfget下載同一個文件時系統的交互示意圖:

 

▲圖2. 蜻蜓P2P組網邏輯示意圖

 

兩個Host和CM會組成一個P2P網絡,首先CM會查看本地是否有緩存,若是沒有,就會回源下載,文件固然會被分片,CM會多線程下載這些分片, 同時會將下載的分片提供給Host們下載, Host下載完一個分片後, 同時會提供出來給peer下載,如此類推, 直到全部的Host所有下載完。

 

本地下載的時候會將下載分片的狀況記錄在metadata裏, 若是忽然中斷了下載,再次執行dfget命令, 會斷點續傳。

 

下載結束後, 還會比對MD5,以確保下載的文件和源文件是徹底一致的。蜻蜓經過HTTP cache協議來控制CM端對文件的緩存時長,CM端固然也有本身按期清理磁盤的能力, 確保有足夠的空間支撐長久的服務。

 

在阿里還有不少文件預熱的場景,須要提早把文件推送到CM端, 包括容器鏡像、索引文件、業務優化的cache文件等等。

在初版上線後,咱們進行了一輪測試, 結果以下圖:

 

▲圖3. 傳統下載和蜻蜓P2P下載測試結果對比圖

 

X軸是客戶端數量, Y軸是下載時長,

文件源:測試目標文件200MB,(網卡:千兆bit/s)

Host端:百兆bit/s網卡

CM端:2臺服務器(24核 64G,網卡:千兆bit/s)

 

從這個圖能夠看出兩個問題:

1.    傳統模式隨着客戶端的增長, 下載時長跟着增長,而dfget能夠支撐到7000客戶端依然沒變好

2.    傳統模式到了1200客戶端之後就沒有數據了,由於數據源被打爆了

 

每一年雙11以前都是發佈高峯期,15年雙11就是靠蜻蜓完美渡過了。

從發佈系統走向基礎設施

 

15年雙11後,蜻蜓的下載次數就達到了12萬/月,分發量4TB。當時在阿里還有用別的下載工具,如wget, curl,scp, ftp 等等,也有自建的小規模文件分發系統。咱們除了全面覆蓋自身發佈系統外, 也作了小規模的推廣。到16年雙11左右,咱們的下載量就達到了1.4億/月,分發量708TB。業務增加了近千倍。

 

16年雙11後咱們提出了一個更高的目標, 咱們但願阿里大規模文件分發和大文件分發90%的業務由蜻蜓來承擔。咱們但願蜻蜓成爲全集團的基礎設施。

 

我但願經過這個目標錘鍊出最好的P2P文件分發系統。此外也能夠統一集團內全部的文件分發系統。統一可讓更多的用戶受益,但統一歷來不是終極目標,統一的目的是:

1.    減小重複建設

2.    全局優化

只要優化蜻蜓一個系統, 全集團都能受益。好比咱們發現系統文件是天天全網分發的, 而光這一個文件壓縮的話就能給公司天天節省9TB網絡流量。跨國帶寬資源尤爲寶貴。而若是你們各用各的分發系統, 相似這樣的全局優化就無從談起。

因此統一勢在必行!

在大量數據分析基礎上,咱們得出全集團文件分發的量大概是3.5億次/周, 而咱們當時的佔比只有10%不到。

 

通過半年努力,在17年4月份,咱們終於實現了這個目標, 90%+的業務佔有率。業務量增加到3億次/周(跟咱們以前分析的數據基本吻合),分發量977TB,這個數字比半年前一個月的量還大。

固然這裏不得不說跟阿里容器化也是密不可分的,鏡像分發流量大約佔了一半。下面咱們就來介紹下蜻蜓是如何支持鏡像分發的。在說鏡像分發以前固然要先說下阿里的容器技術。

阿里的容器技術

容器技術的優勢天然不須要多介紹了,全球來看, 容器技術以Docker爲主佔了大部分市場,固然除此以外還有其餘解決方案,好比rkt,Mesos Uni Container, LXC等,而阿里的容器技術命名爲Pouch。早在2011年,阿里就自主研發了基於LXC的容器技術T4,只是當時咱們沒有創造鏡像這個概念, T4仍是當作虛擬機來用, 固然比虛擬機要輕量的多。

2016年阿里在T4基礎上作了重大升級,演變爲今天的Pouch,而且已經開源。目前Pouch容器技術已經覆蓋阿里巴巴集團幾乎全部的事業部,在線業務100%容器化,規模高達數十萬。鏡像技術的價值擴大了容器技術的應用邊界,而在阿里如此龐大的應用場景下,如何實現高效「鏡像分發」成爲一個重大命題。

回到鏡像層面。宏觀上,阿里巴巴有規模龐大的容器應用場景;微觀上,每一個應用鏡像在鏡像化時,質量也存在良莠不齊的狀況。

理論上講用鏡像或者用傳統「基線」模式,在應用大小上不該該有很是大的區別。但事實上這徹底取決於Dockerfile寫的好壞,也取決於鏡像分層是否合理。阿里內部其實有最佳實踐,可是每一個團隊理解接受程度不一樣, 確定會有用的好壞的之分。尤爲在一開始,你們打出來的鏡像有3~4GB這都是很是常見的。

 

因此做爲P2P文件分發系統,蜻蜓就有了用武之地,不管是多大的鏡像,不管是分發到多少機器, 即便你的鏡像打的很是糟糕, 咱們都提供很是高效的分發,都不會成瓶頸。這樣就給咱們快速推廣容器技術,讓你們接受容器運維模式,給予了充分消化的時間。

容器鏡像

在講鏡像分發以前先簡單介紹下容器鏡像,咱們先看下Ubuntu系統的鏡像:咱們能夠經過命令 docker history ubuntu:14.04 查看 ubuntu:14.04,結果以下:

須要額外注意的是:鏡像層 d2a0ecffe6fa 中沒有任何內容,也就是所謂的空鏡像。

鏡像是分層的,每層都有本身的ID和尺寸,這裏有4個Layer,最終這個鏡像是由這些Layer組成。

 

Docker鏡像是經過Dockerfile來構建,看一個簡單的Dockerfile:

鏡像構建過程以下圖所示:

 

能夠看到,新鏡像是從 base 鏡像一層一層疊加生成的。每安裝一個軟件,就在現有鏡像的基礎上增長一層。

 

當容器啓動時,一個可寫層會被加載到鏡像的頂層,這個可讀可寫層也被稱爲「容器層」,容器層之下都是「鏡像層」,都是隻讀的。

若是鏡像層內容爲空,相應的信息會在鏡像json文件中描述,若是鏡像層內容不爲空,則會以文件的形式存儲在OSS中。

鏡像分發

▲圖4. Docker 鏡像下載流程圖

 

以阿里雲容器服務爲例, 傳統的鏡像傳輸如上圖所示,固然這是最簡化的一種架構模式, 實際的部署狀況會複雜的多, 還會考慮鑑權、安全、高可用等等。

 

從上圖能夠看出來,鏡像傳輸跟文件分發有相似的問題, 當有一萬個Host同時向Registry請求時, Registry就會成爲瓶頸,還有海外的Host訪問國內Registry時候也會存在帶寬浪費、延時變長、成功率降低等問題。

 

下面介紹下Docker Pull的執行過程:

▲圖5. Docker 鏡像分層下載圖

 

Docker Daemon調用Registry API獲得鏡像的Manifest,從Manifest中能算出每層的URL,Daemon隨後把全部鏡像層從Registry並行下載到Host本地倉庫。

 

因此最終,鏡像傳輸的問題變成了各鏡像層文件的並行下載的問題。而蜻蜓擅長的正是將每層鏡像文件從Registry用P2P模式傳輸到本地倉庫中。

 

那麼具體又是如何作到的呢?

 

事實上咱們會在Host上啓動dfGetproxy,Docker/Pouch Engine的全部命令請求都會經過這個proxy,咱們看下圖:

 

▲圖6. 蜻蜓P2P容器鏡像分發示意圖

首先docker pull命令,會被dfget proxy截獲,而後由dfget proxy向CM發送調度請求,CM在收到請求後會檢查對應的下載文件是否已經被緩存到本地,若是沒有被緩存,則會從Registry中下載對應的文件並生成種子分塊數據(種子分塊數據一旦生成就能夠當即被使用),若是已經被緩存,則直接生成分塊任務,請求者解析相應的分塊任務並從其餘peer或者supernode中下載分塊數據,當某個Layer的全部分塊下載完成後,一個Layer也就下載完畢了,一樣,當全部的Layer下載完成後,整個鏡像也就下載完成了。

 

蜻蜓支持容器鏡像分發,也有幾個設計目標:

1. 大規模併發:必須能支持十萬級規模同時Pull鏡像

 

2. 不侵入容器技術內核(Docker Daemon, Registry),也就是說不能改動容器服務任何代碼。

 

3. 支持Docker, Pouch, Rocket ,Hyper等全部容器/虛擬機技術

 

4. 支持鏡像預熱(構建時就推送到蜻蜓集羣CM

 

5. 支持大鏡像文件 (至少30GB

 

6. 安全

Native Docker V.S 蜻蜓

咱們一共作了兩組實驗:

 

實驗一:1個客戶端

1.    測試鏡像大小:50MB、200MB、500MB、1GB、5GB

2.    鏡像倉庫帶寬:15Gbps

3.    客戶端帶寬:雙百兆bit/s網絡環境

4.    測試規模:單次下載

 

▲圖7. 單客戶端不一樣模式對比圖

 

Native和蜻蜓(關閉智能壓縮特性)平均耗時基本接近,蜻蜓稍高一點,由於蜻蜓在下載過程當中會校驗每一個分塊數據的MD5值,同時在下載以後還會校驗整個文件的MD5,以保證下載的文件跟源是一致的;而開啓了智能壓縮的模式下,其耗時比Native模式還低!


 

實驗二:多客戶端併發

 

1.    測試鏡像大小:50MB、200MB、500MB、1GB、5GB

2.    鏡像倉庫帶寬:15Gbps

3.    客戶端帶寬:雙百兆bit/s網絡環境

4.    多併發:10併發、200併發、1000併發   

▲圖8.不一樣鏡像大小和併發數的對比圖

 

上圖能夠看出,隨着下載規模的擴大,蜻蜓與Native模式耗時差別顯著擴大,最高可提速能夠達20倍。在測試環境中源的帶寬也相當重要,若是源的帶寬是2Gbps,提速可達57倍。

 

下圖是下載文件的總流量(併發數 * 文件大小)和回源流量(去Registry下載的流量)的一個對比,

 

▲圖9. 蜻蜓鏡像分發出流量對比圖

 

向200個節點分發500M的鏡像,比docker原生模式使用更低的網絡流量,實驗數據代表採用蜻蜓後,Registry的出流量下降了99.5%以上;而在1000併發規模下,Registry的出流量更能夠下降到99.9%左右。

 

在阿里的效果

 

蜻蜓在阿里投入使用大概已有兩年, 兩年來業務發展迅速,從分發的次數來統計目前一個月接近20億次,分發3.4PB數據。其中容器鏡像的分發量接近一半。

▲圖10. 蜻蜓在阿里文件vs鏡像分發流量趨勢圖

 

在阿里最大的一次分發應該就是今年雙11期間, 要對上萬臺服務器同時下發5GB的數據文件。

走向智能化

 

阿里在AIOps起步雖然不是最先, 可是咱們近年來投入巨大,並在不少產品上有所應用。蜻蜓這個產品中有如下應用:

 

智能流控

 

流控在道路交通中很常見,好比中國道路限速規定,沒有中心線的公路,限速爲40千米/小時;同方向只有1條機動車道的公路,限速爲70千米/小時;快速道路80千米;高速公路最高限速爲120千米/小時等等。這種限速對每輛車都同樣,顯然不夠靈活,因此在道路很是空閒的狀況下道路資源實際上是很是浪費的,總體效率很是低下。

 

紅綠燈其實也是流控的手段,如今的紅綠燈都是固定時間,不會根據現實的流量來作智能的判斷,因此去年10月召開的雲棲大會上,王堅博士曾感慨,世界上最遙遠的距離不是從南極到北極,而是從紅綠燈到交通攝像頭,它們在同一根杆上,但歷來沒有經過數據被鏈接過,攝像頭看到的東西永遠不會變成紅綠燈的行動。這既浪費了城市的數據資源,也加大了城市運營發展的成本。

 

蜻蜓其中一個參數就是控制磁盤和網絡帶寬利用率的, 用戶能夠經過參數設定使用多少網絡IO/磁盤IO。如上所述,這種方法是很是僵化的。因此目前咱們智能化方面的主要思想之一是但願相似的參數不要再人爲來設定,而是根據業務的狀況結合系統運行的狀況,智能的決定這些參數的配置。最一開始可能不是最優解,可是通過一段時間運行和訓練後自動達到最優化的狀態。保證業務穩定運行同時又儘量的充分利用網絡和磁盤帶寬,避免資源浪費。

 

智能調度

 

分塊任務調度是決定整個文件分發效率高低與否的關鍵因素,若是隻是經過簡單的調度策略,好比隨機調度或者其餘固定優先級的調度,這種作法每每會引發下載速率的頻繁抖動,很容易致使下載毛刺過多,同時總體下載效率也會不好;爲了最優化任務調度,咱們經歷了無數次的嘗試和探索,最終經過多維度(好比機器硬件配置、地理位置、網絡環境、歷史下載結果和速率等等維度的數據)的數據分析(主要利用了梯度降低算法,後續還會嘗試其餘算法)智能動態決定當前請求者最優的後續分塊任務列表。

 

智能壓縮

 

智能壓縮會對文件中最值得壓縮的部分實施相應的壓縮策略,從而能夠節約大量的網絡帶寬資源。


 

對容器鏡像目前的實際平均數據來看,壓縮率(Compression Ration)是40%,也就是說100MB鏡像能夠壓縮到40MB。針對1000併發規模,經過智能壓縮能夠減小60%的流量。

 

 

安全

在下載某些敏感的文件(好比祕鑰文件或者帳號數據文件等)時,傳輸的安全性必需要獲得有效的保證,在這方面,蜻蜓主要作了兩個工做:

1、支持攜帶HTTP的Header數據,以知足那些須要經過header來進行權限驗證的文件源;

2、利用對稱加密算法,對文件內容進行傳輸加密。

 

開源

 

隨着容器技術的流行,容器鏡像這類大文件分發成爲一個重要問題,爲了更好的支持容器技術的發展,數據中心大規模文件的分發,阿里決定開源蜻蜓來更好的推動技術的發展。阿里將持續支持開源社區,並把本身通過實戰檢驗的技術貢獻給社區。敬請期待。

 

商業化

 

蜻蜓除了用於阿里集團內部容器化,也徹底兼容社區版Docker,能夠和[阿里雲容器服務](https://www.aliyun.com/product/containerservice)和飛天專有云敏捷版(https://yq.aliyun.com/articles/224507)無縫結合在一塊兒,在公共雲和專有云環境下支撐大規模的容器鏡像分發。

總結

 

蜻蜓經過使用P2P技術同時結合智能壓縮、智能流控等多種創新技術,解決大規模文件下載以及跨網絡隔離等場景下各類文件分發難題,大幅提升數據預熱、大規模容器鏡像分發等業務能力。

蜻蜓支持多種容器技術,對容器自己無需作任何改造,鏡像分發比natvie方式提速可高達57倍,Registry網絡出流量下降99.5%以上。承載着PB級的流量的蜻蜓,在阿里已然成爲重要的基礎設施之一,爲業務的極速擴張和雙11大促保駕護航。

 

Reference

 

【1】Docker Overview:

https://docs.docker.com/engine/docker-overview/

【2】Where are docker images stored:

http://blog.thoward37.me/articles/where-are-docker-images-stored/

【3】Image Spec:

https://github.com/moby/moby/blob/master/image/spec/v1.md

【4】Pouch開源地址:

https://github.com/alibaba/pouch

【5】蜻蜓開源地址:

https://github.com/alibaba/dragonfly

【6】阿里雲容器服務:

https://www.aliyun.com/product/containerservice

【7】飛天專有云敏捷版:

https://yq.aliyun.com/articles/224507

【8】雲效:

https://www.aliyun.com/product/yunxiao

相關文章
相關標籤/搜索