雲端架構

jingxianli0922發表於2014-12-08

 背景

  在看阿凡達的時候,感嘆著他們介面的統一,和獲取知識的便利性。有時候在想,現在很多企業所做的工作,不就是要提供這類服務嗎。設想一下,我們有一朵公有云,儲存了使用者的資料、邏輯關係,提供標準的通訊介面,然後大家各自開發豐富的展現邏輯,讓雲端變的豐富多彩。這次很榮幸能接到這個議題,談談我個人對這朵雲的理解。

  每個人心中都有自己的一朵雲,在我設想中,應該存在這麼一種公有服務,它能夠幫助使用者隨時隨地的獲取自己的資料,與朋友交流,獲取好友最新狀態。在這服務之上,我們有這麼一個平臺,它能夠給使用者提供二次開發的介面,讓開發者根據使用者資料開發豐富的展現層,並且提供這些展現層的執行平臺。

  我們需要的雲端服務

  為了完成這個功能,我們需要什麼準備?

  雲端儲存:提供使用者資料的儲存功能。讓使用者方便的獲取自己的資料。

  通訊系統:提供以Mail,IM為基礎的通訊方式。

  通知系統:好友行為推送,能夠把握好友最新動態,或者告知好友你在幹什麼。

  在這三個基本服務之上,使用者可以開發大量的運用。比如“音樂盒”用於線上播放雲端儲存的MP3,圖片系統用於管理、分享,美化自己的照片……然而,使用者開發完邏輯應用之後,需要機器執行這個運用。因此,第四個基本服務執行平臺孕育而生,它提供所有云應用執行的基本資源,包括記憶體、CPU、作業系統等。

  這四個基本要素構建成一個面向終端使用者的作業系統平臺(也就是我們的雲),它能夠隨時被訪問,通過瀏覽器或者手機的App。滿足使用者在任意時刻團購,玩三國殺,看視訊,聽音樂等需求。為了方便開發者開發更多的應用,我們抽象一種程式設計模式,提供豐富的SDK,加速應用的開發。由於雲端服務,有很大一部分會被手機等嵌入式裝置訪問,於是需要各種平臺的程式設計框架(android、iOS)。程式設計框架將更加關心業務邏輯,遮蔽分散式細節和運維問題。

  在滿足這些開發便利性的前提下,為鼓勵使用者開發,提高APP質量和數目,需要一套良好的收費系統,幫助開發者更好的盈利。

  圍繞這這朵雲,一點點的展開,發現想說的東西太多,今天我們就談談其中的兩個核心架構:雲端儲存和應用執行平臺(App Engine)。為什麼要選這兩個?因為雲的核心就是儲存和計算,其它都構建在儲存和計算之上的基礎服務和使用者運用。

  雲端儲存架構

  雲端儲存主要是為了儲存使用者資料,方便使用者訪問。它涉及了三方面的技術:

  • 底層架構。包括:分散式儲存、檔案目錄管理、使用者許可權系統。
  • 下載優化:各地CDN支援、客戶端下載技術(P2P)。
  • 資料訪問前端優化

  底層架構設計的要點

  首先我們比較一下跟傳統離線儲存的設計指標差異

  1. 單個檔案體積不大

    儲存網際網路使用者的資料,註定檔案不會很大。我們只要支援0-100G左右的單檔案大小即可。為什麼使用者檔案會到100G?因為我們要保證使用者能分享高清電影。另外相對於海量的容量,如果單檔案過小,那麼海量空間也沒啥意義。多媒體是促進磁碟發展的動力。

  2. 檔案數會很多

    跟GFS不一樣,雲端儲存的檔案數是海量的。因為每個人都會儲存他們的文件、mp3、圖片……這注定了單機儲存全部檔案的node是不可能的。

  3. 需要目錄管理

    我們需要呈現傳統作業系統類似的目錄管理方式。另外根據雲端儲存檔案數量多的特點,我們要提供可靠的檢索做檔案管理。

  4. 讀寫模式特殊性

    使用者對檔案的訪問模式是一次寫入,多次讀取,讀取支援隨機位置的讀取(比如視訊從中間開始播放)等。另外考慮在使用者頻寬條件下,100M的檔案也算是大檔案了,我們要需要支援斷點續傳功能。另外,存在對單檔案的高併發訪問。

  5. 檢索和訪問的實時性

    使用者上傳的資料,在上傳成功之後,就應該能訪問到完整的資料。並且在檢索的時候就能夠體現出來。因此不僅要求儲存系統要求實時性,而且檢索系統也有要求實時性。

  歸納一下,因為檔案太小導致檔案數過多,需要專門的目錄儲存;針對檔案的訪問模式,我們需要設計一個比較合理的檔案格式;提升檢索的實時性。

  檔案格式介紹

  一個檔案需要的儲存資料:Meta資訊和資料塊。Meta資訊儲存這個檔案的詳細資訊,包括檔名、大小、檔案型別(doc或者mp3)、MD5、建立者、具體資料塊的存放位置、資料塊大小,以及該檔案格式的版本資訊等。資料塊是真正儲存的檔案資料。

  我們將一個完整的檔案,物理切成多塊。比如一個1G的檔案,我們按照1M為塊大小,切成1024塊,然後將1024個塊資料雜湊到N臺機器中去。從而保證檔案具備高併發的特點,而且也能夠方便的為整個叢集提供擴充套件能力。然後我們會將這1024個塊的具體位置記錄到檔案的meta資訊中,方便訪問。

  因此,我們需要一個邏輯檔案的訪問入口(WebServer),和儲存這些資料塊與Meta資訊的叢集Chunk Cluster和Meta Cluster。

  將一個不大的檔案分散到各臺機器上儲存有什麼好處?

  1. 方便做負載均衡和叢集擴容
  2. 將熱門檔案的流量分散到各臺機器上,使熱門檔案的高頻訪問對後端影響降低。

  這個檔案格式的設計,大家可能會覺得檔案很大的話,Meta資訊因需要儲存的塊位置而導致體積過大。其實這個問題,可以通過二級索引塊來解決。

  儲存架構的工作原理

  如上圖,WebServer在接收Http請求的時候,會解析引數,然後根據Meta Cluster提供的Meta資訊,讀取相關塊,返回給請求者。Chunck Cluster和Meta Cluster的設計都是一樣的,就是提供一套NoSQL系統,支援針對Key(字串) - value(二進位制)的增刪改查。但是考慮到訪問頻率的不同,我們需要針對不同的硬體做單機的優化,比如廉價的Sata盤存放相對靜止的資料,SSD盤存放訪問頻率過高的資料。

  NoSQL叢集不是我們這篇檔案要簡述的話題,有機會可以詳談。不過即使是分散式系統,我們也應注重模組的單機效能。因為如果我們的模組單機效能提高一倍,那麼我們的叢集規模就會下降一倍。在上萬臺機器中,節約的成本是非常可觀的。我們如何衡量這個儲存系統的單機引擎效能呢?方法很簡單,如果一個單機模組,能夠將網路卡吞吐跑滿或者磁碟順序讀寫吞吐跑滿,對於儲存模組本身來說,可以了。

  目錄管理系統實現

  海量檔案的目錄管理,很難。這裡,我們採用一個分散式有序表的方式來解決,分散式有序表也是NoSQL的一種。它對儲存的資料,提供基於字典序的遊標查詢。比如:我們將所有的使用者檔名放入有序表中,該系統就會產生根據檔名排序的分散式陣列,如下:

  [/a.doc; /a/a.doc; /a/b.doc; /a/c.doc; /b.doc; /b/b/b.doc]

  在執行ls /a/命令的時候,我們會尋找/a/的遊標得到/a/a.doc,接著我們開始遍歷這個遊標,直到不是/a/打頭為止。如果該過程中碰到子目錄,程式會會通過二分查詢直接跳過子目錄,從而防止遍歷過多。如果數目過多,我們會展現100條,其它隱藏。目錄管理,主要是給使用者組織自己資料的時候用的,理論上,使用者不會在一個目錄下放太多的檔案,即使太多,也沒關係,我們就顯示100條,然後提供下一頁的按鈕(因為下一頁的遊標位置我們是知道的)。

  實時檢索系統

  討論這個議題的時候,需要假設我們已經有一個傳統的檢索系統,然後想辦法提高檢索的實時性。我們設計一個記憶體索引,把使用者新增的檔案,對檔名切詞後放到記憶體中檢索,檢索的結果參與最終的合併。每隔五分鐘merge到傳統檢索系統中,然後釋放記憶體。雲端儲存,不像網際網路網頁,在5分鐘之內,僅檔名的索引,資料量不可能太大,所以記憶體不會是瓶頸。進一步的,我們可以對檔案的內容作檢索,但是檔案內容沒有必要做到實時。

  許可權系統

  使用者許可權系統,對於雲端儲存來說,也是個使用者檔案,所以沒什麼特別的,只不過我們需要專門的快取做訪問優化。因為每一次讀寫請求,都要判斷訪問者是否有相關的許可權。

  CDN技術

  P2P技術和CDN支援,主要是為了減少頻寬成本而做的,在雲端儲存這種資料量巨大的服務中,這兩種技術,顯的尤為重要。這兩塊是兩個專題,我們在這裡不多做介紹。不過這兩個技術在解決熱點問題效果比較好,但是海量檔案並不是所有檔案都放CDN的,因此有些工作,資料訪問前端不得不做。

  資料訪問與客戶端優化考慮

  客戶端訪問速度差別,是我們要考慮的問題。如果是內部的訪問,頻寬可以保證是1000M以上,但是面向網際網路使用者,各種各樣的頻寬需求都有,比如GPRS、3G、ADSL,從20k-16M不等。這就要求我們的前端技術,在處理這些請求下要工作的很好。另外我們還要考慮在正常服務下,網路頻寬最小化,比如一個視訊是100分鐘,我們就應該保證100分鐘內傳完,滿足正常播放,不能太快,因為太快,你不能保證使用者有耐心看完,可能他就看10分鐘,然後就關了,於是後面傳輸的頻寬全浪費了。如果是使用者下載,那麼當然是越快越好。這些控制,我們都通過WebServer來實現。

  WebServer最主要的功能就是高併發支援,限速。再加上雲端儲存的資料是海量的,傳統的Apache做WebServer肯定不適合,這裡我們採用非同步的WebSever比如lighttpd或者nginx,然後對客戶端控制程式碼進行速度控制。為了支援大檔案的斷點上傳,我們需要有一個專門的客服端,能夠將檔案分塊上傳。Webserver必須支援根據md5查詢這個檔案哪些塊已經上傳了,哪些沒上傳,從而通知客戶端正常工作。

  雲端儲存有很多節約頻寬的優化,比如上傳檔案的時候,先上傳md5,如果雲端已經存在,就不需要上傳了,這樣可以做到大檔案的秒傳,節約網路頻寬。另外它提供對外標準的Http協議,可以採用迅雷等p2p軟體下載,從而提高訪問速度,減少伺服器頻寬衝擊。為了資料安全性,我們還得提供https協議的資料訪問。

  App Engine

  完成雲端儲存的設計之後,我們需要一個開發平臺,這個開發平臺提供使用者邏輯的執行環境。這環境包括

  1. MYSQL叢集化管理
  2. 離線任務的處理
  3. PHP的執行環境

  MySQL叢集化管理

  因為雲端儲存沒有提供關係資料的儲存功能,為了降低使用者的開發門檻,我們需要一個MYSQL的叢集化來完成類似的功能。MYSQL的叢集化,主要是完成MYSQL讀寫分離和主從同步功能。

  通過這種架構,保證了開發者不需要關心MYSQL的資料故障等問題。因為MYSQL Proxy會自動的進行主從切換和讀寫分離。這裡我們要開發的就是解析SQL語句,完成相關的使用者認證,並完成相關的後臺轉發、接收。

  MYSQL的叢集化管理沒有解決分散式的問題,這個地方我們認為不需要解決。因為網際網路線上業務類的關係資料不會太大,大的資料都放到雲端儲存裡面了,資料庫只存索引。還有,資料庫的分庫分表也相對成熟,索引資料也很難快速膨脹。如果使用者有對分散式索引的需求,可以考慮前面我們談到的有序表。

  離線任務處理

  離線任務處理主要解決,使用者需要做大量的cpu密集型的工作,包括圖片轉化,視訊轉化等。我們這裡採用了一套訊息佇列的方式進行離線處理。使用者將處理請求扔給訊息佇列,執行機獲取訊息佇列的訊息之後,會執行相關的的使用者程式碼。

  php執行環境

  PHP執行環境,主要解決PHP的分散式化問題。雲平臺上跑的服務,千奇百怪,可能因為沒有流量,只用到實際機器的千分之一,也可能擁有鉅額流量,需要上百臺機器支援。當然大部分服務沒有什麼流量。對於傳統的虛擬化來說,1臺機器能虛擬化成32臺,已經慢的不行。這樣,一臺物理機只能部署32個app運用,對於基礎架構來說是不可接受的。因為網際網路上的雲端運用,會急劇膨脹,所以我們需要一種新的虛擬化架構,能將機器的粒度切的更細。

  這裡我們使用PHP為開發語言展示一個輕量級的虛擬化技術。我們通過輕量級虛擬化技術,為每個使用者分配一組FAST CGI程式資源,通過Web端的排程,將請求引到各自的FAST CGI程式組中處理。這樣一臺機器能啟動多少個程式,我們就能虛擬化多少份。

  如果網站流量很大,單機處理不了,該如何解決?我們是通過FAST CGI程式個數來排程的,單機資源不夠的情況下,我們會在多臺機器上分配程式,組成一個FAST CGI組,然後通知Web端,這個網站的請求可以分流到哪些FAST CGI中去。我們會有一個總控的Master來觀察各臺機器的負載,從而判斷是否要遷移FAST CGI程式。FAST CGI程式的遷移是簡單的,這臺機器KILL,在另外一臺機器重啟即可。

  這個是我們PHP執行環境的架構。

  架構依賴於資源定位服務。資源定位通知前端接入,哪些機器負載還行,可以引流,哪些已經故障,或者壓力過大,不能引流。當A.baidu.com的流量過來的時候,前端接入會解析域名,並且根據資源定位獲取的資料(本地有快取),分發到對應的某臺機器的FAST CGI埠上,執行PHP程式碼後返回。因為FAST CGI讀取的使用者程式碼儲存在網路檔案系統中,所以前端接入無論選擇哪臺FAST CGI都能夠有效的做處理。在實際過程中,我們發現網路檔案系統對效能,尤其是HTML的訪問效能影響很大,因此我們對每臺機器做了單機快取。不過Cache失效是個非常難解決的問題,我們這裡採用的方法是一但檔案發生修改,資源定位會通知所有客戶機的該檔案快取失效,而且更新必須走同一的入口。由於我們只儲存程式碼,效果還可以。有了分散式的網路檔案系統,使用者程式碼更新也變得異常簡單。只要更新完成,通知快取失效即可。

  另外一個問題,如果執行平臺跑大量的垃圾網站,比如很多一天只有少量請求的網站。用輕量級虛擬化,即使1臺機器切出2000千份資源,還是很浪費的。對於這種運用,我們採用了FAST CGI複用,即很多小網站的請求都落到1個FAST CGI上,然後FAST CGI根據目前處理的網站,來獲取相關的配額控制。真正做到資源消耗跟訪問量成正比,沒訪問沒成本。這裡可能用CGI更好點,不過為了架構統一下,這點優化不算麻煩。

  小結

  簡單介紹了App Engine所具有的能力,一個PHP的輕量級虛擬化,能夠將1臺機器虛擬成萬分之一,也能將萬臺機器合成1個大的虛擬環境。實現從萬分之一到萬倍計算資源的漸進分配。它成功解決了一個網站,從小到大的計算能力的無限擴充套件問題。

  也介紹了雲端儲存所具備的能力,它支援海量的資料儲存,成功解決了一個網站,從小到大的儲存能力無限擴充套件問題。

  整個雲端運用,就是基於強悍可伸縮的計算能力和儲存能力之下構建的網站。我們真正做的就是邏輯開發,和各個終端下的特殊展現形式。用這套架構,實現一個視訊分享網站,電子書閱讀網站是容易的。減少了雲端應用的開發門檻,整個雲端產品也將豐富多彩。它們都用統一的架構,計算和儲存分離,程式開發無狀態化,永續性儲存放在雲端儲存中。

  有給力的基礎架構,雲端運用隨手拈來。目前在百度公司內部,這種架構已經有成型的運用,它極大的提高了應用服務的開發效率,降低服務運維成本和開發人員的技術門檻。百度內部雲平臺遷移了大量的線上服務,有關百度的最新進展和資料,大家可以參考《QCon北京2011全球企業開發大會》公佈的一些關於BAE的資料。

相關文章