簡述:
又拍雲存儲是一個提供檔案快速存儲及通過CDN系統快速分發至全國各地通路的綜合型服務商,目前主要提供圖檔和音頻檔案為主的靜态小檔案服務。海量小檔案存儲一直是業界難題,而我們資料中心的存儲系統就是一個大型分布式Key/Value資料庫,可很好解決小檔案的存儲問題(業界也有不少開源的分布式存儲系統可使用,本文不再詳述)。但對于小檔案通路依然無法取得很好的性能,尤其是面對海量通路的情況,通路壓力呈幾何級數增大,對此我們有必要在此基礎上加入CDN服務,以降低海量通路對資料中心造成的壓力(以我們監控資料分析得到的結果:使用CDN服務可降低98%的壓力)。
考慮到傳統CDN系統架構是面向多種類型客戶服務,如下載下傳站或視訊站點,這些都是大檔案,而還有一部分圖檔或音樂站點則是小檔案為主,傳統架構隻能在此取得一個平衡點,盡量對多種類型進行優化。但又拍雲存儲目前以小檔案為主,是以我們的CDN系統架構要以小檔案優化為主。同時面對客戶的需求多樣化,我們還在傳統CDN服務基礎上加入一些定制功能,比如圖檔縮略圖、圖檔水印和音頻轉碼這些附加功能。是以我們自主研發了UpCDN系統,接下來大家可以對此進行深入了解。
業務場景:
- 數萬個網站客戶
- 超過百億個小檔案,2PB的源資料,并且這個數字仍以每天數TB的規模在增長
- 每秒提供數十萬次通路請求
讨論:
如使用傳統的CDN架構來提供服務,會面臨這些問題:
- 小檔案過多,讀取性能差
- 服務的網站數量大,難以提供完善的防盜鍊服務
- 客戶需求複雜:
- 流量統計
- 日志報表
- 日志下載下傳
- 圖檔縮略圖
- 圖檔水印
- 音頻轉碼
- 等等…
要解決小檔案讀取性能問題,可使用SSD固态硬碟解決,但考慮到SSD固态硬碟成本高昂,并不适合大面積使用,而CDN緩存則是要盡可能緩存更多的檔案在本地節點,才可充分降低對存儲中心的通路壓力。那麼SSD固态硬碟和SAS普通硬碟混合使用是最合适的,但Squid隻支援根據存儲對象大小來配置設定多種存儲媒體和排程,為此需要開發一個緩存排程系統。
對于防盜鍊政策,一般是直接在Nginx配置檔案上加入。但如果寫入大量的防盜鍊規則,會使得Nginx的配置檔案非常龐大(這不反人類了嘛),日後的管理和維護都會是問題。那唯有在Nginx基礎上加入動态防盜鍊功能,才能很好的解決這個問題。并且可降低運維人員的工作。
流量統計,面對40多個機房200多台伺服器,要做到即時統計會非常困難。整個系統每秒幾十萬個請求,要将這些資訊一一發送到資料中心做彙總統計,顯然不現實。如果要做到即時統計的能力,隻能在前端節點上進行資料壓縮處理(這裡指資料的彙總,并不是gzip類文本壓縮),再傳到資料中心,方可實作。
為此我們的CDN系統将會包括:防盜鍊、流量統計、緩存排程和防攻擊等多個業務功能。考慮到前端CDN節點的通路請求量非常大,每秒數十萬個請求,平台每台伺服器要接受幾千次通路,業務處理能力必須非常高才能應付。以我們多年經驗分析,使用Squid來做CDN緩存的性能最好,高通路壓力下也不會有太大影響,非常适合我們的業務場景。但Squid本身軟體架構很獨立、擴充性差,并不适合做二次開發,如需要增加前面所說的幾個業務功能會非常費勁。為此我們選擇了擴充性很好,且性能高的Nginx作為反向代理伺服器,架設在最前端,所有的業務功能以Nginx子產品的形式加入進去。這樣看來Nginx+Squid可滿足目前所有需求:)
我們就以此為基礎研發UpCDN系統。
UpCDN系統介紹:
整體系統分為三層架構,第一層是部署在各個地區的CDN前端節點;第二層是部署在電信和聯通網絡骨幹的中間節點;第三層是接入電信、聯通、移動和鐵通線路的核心機房,雲存儲服務的資料中心節點。
前端CDN節點是基于Nginx+Squid進行搭建,主要包括防盜鍊、流量統計、緩存排程和防攻擊等多個業務子產品:
系統設計的主要目标:
- 高吞吐和低延遲。我們的CDN系統必須能提供海量通路請求,每秒幾十萬個請求是常态,是以我們的系統容量是以百萬請求為基礎進行部署。并且每次請求的處理時間必須要快,這不僅能提升使用者體驗還可節省伺服器硬體成本。也是以前端CDN節點上的業務系統均以Nginx子產品的形式,主要使用C語言進行開發。
- 功能強大且豐富。因是雲存儲服務,客戶需求比較多,如防盜鍊、流量統計、日志報表等功能是必須的。可能A客戶不需要流量統計,B客戶隻需要日志報表功能,但也是以要面向A、B客戶都提供這些功能。
- 容錯可擴充。在大規模系統中,伺服器當機每天都會發生。即使系統崩潰或硬體故障不可避免,也不能影響到我們整體服務,哪怕某個機房停電,UpCDN系統也要自動容錯。是以前端CDN節點一般配以5台或10台伺服器為一組提供服務,使用LVS進行容災和負載均衡,而Squid的容災和均衡則由Nginx負責;面向CDN機房級别的容災處理,則由資料中心的監控系統進行排程,當某個機房出現通路故障,資料中心會第一時間把該機房剔除CDN網絡(因是主動式排程,剔除操作會有幾十秒的TTL延遲)。
- 簡單可維護。前端CDN節點的數量多,運維人員需管理數百台伺服器,工作量顯而易見,并且人手操作容易犯小錯誤,是以我們盡最大的努力把UpCDN系統建構成全自動化的管理模式。前端CDN節點的伺服器就是一個個的Copy,配上IP就能接入到CDN系統上提供服務。讓運維人員可以從軟體系統中脫身,隻需關注硬體維護即可。
系統子產品功能與實作:
防盜鍊子產品
防盜鍊子產品在Nginx啟動時并沒有任何防盜鍊政策,但會到資料中心擷取一份完整的客戶域名清單,但針對某個空間域名的具體防盜鍊政策是未擷取的,而是在某個URL請求通路過來的時候觸發政策更新動作(該次請求隻判斷是否是合法的空間域名,如果該URL的空間域名不在客戶清單上是不允許被通路的),前往資料中心擷取該URL對應空間域名的防盜鍊政策,并以自定好的資料結構存儲于Nginx的共享記憶體中,下次通路該空間的所有URL都能檢索到對應的防盜鍊政策。也就是說防盜鍊子產品是以按需被動觸發、主動更新的模式進行操作,本地的防盜鍊政策不會跟資料中心保證嚴格一緻,通常會延遲幾分鐘。因防盜鍊子產品會每間隔幾分鐘前往資料中心擷取一份防盜鍊政策更新的客戶清單,如檢測到某個空間域名的防盜鍊政策有更新,将把本地共享記憶體中的對應記錄标記為“需更新”,當該空間再次有通路請求進來的時候再主動觸發一個更新操作。這樣做的好處是,客戶更新防盜鍊政策,在資料中心的操作相對減少很多,都交由前段CDN伺服器各自前來更新政策,但缺點是政策更新有延時,另外要注意CDN伺服器數量太多或者服務的客戶數量大,那發起政策更新的請求也将加大,是以我們采用0~5分鐘随機定期檢查的方法,以降低對資料中心的查詢壓力。
截至到目前統計到的資料有:
空間域名兩萬多個,也就是說有兩萬多個防盜鍊政策存儲在Nginx的共享記憶體中,存儲在Nginx共享記憶體中防盜鍊政策的記憶體消耗大概在50MB/萬個。可見防盜鍊子產品并沒消耗太多的系統資源,就能很好的解決問題。
流量統計子產品
為降低資料統計的資料量,我們采用先在前端進行初步統計一個中間結果再交予資料中心進行大彙總的模式。每個URL通路請求進入Nginx,将通過流量統計子產品并把該次請求的内容大小(如:102400位元組)記錄到該請求對應的空間域名記錄下,而不是直接就把這次請求的流量數字報到後端資料中心。在前端的流量統計子產品上暫時保留5分鐘的記錄,每隔5分鐘後進行每個空間域名的彙總統計,得到一個中間值再報入到資料中心進行全部節點的彙總統計。
這樣一來,資料量從幾百萬條記錄降低到每5分鐘幾百條記錄,那麼在資料中心的彙總統計就相對簡單很多。
緩存排程子產品
排程子產品在Nginx共享記憶體中存有幾百萬條URL資訊,這些資訊是标記某個URL應該排程到SSD磁盤或者SAS磁盤。這數百萬條記錄主要通過Nginx内部提供的RbTree算法進行查找,百萬條記錄,最多隻需20步就能定位到記錄。而我們在RbTree算法基礎上加入了LRU和MRU算法,以實作在固定範圍内對這些URL進行排序操作,當某些URL通路密度明顯大于其他URL時,它将被調到SSD磁盤的Squid緩存進行讀寫。
雖然每個通路請求都會經過緩存排程子產品的判斷,但子產品的判斷速度非常快,不會帶來任何延遲。可将熱門内容(占通路總量70%以上)都被排程到SSD磁盤上讀取,明顯提高系統整體性能。
防攻擊子產品
該子產品核心算法跟緩存排程子產品類似,都是要對大量的URL進行排序,對通路量大的URL進行判斷。如果某個URL的通路頻密度超過正常門檻值,系統将對此URL的所有請求進行初步屏蔽處理(該次屏蔽以302重定向的方式進行保護,如果該次請求不是浏覽器發起的正常通路一般是不會識别302重定向信号,進而可屏蔽掉機器重新整理類型的攻擊),如情況還繼續惡化,系統将禁止該URL的通路請求,每隔5分鐘再次稽核該URL的請求量是否恢複到正常門檻值,自動判斷是否可以解除禁止。
子產品開發要點:
- 效率,資源占用少。主要以Nginx子產品,C語言為主進行開發,而個别複雜且通路密度較低的業務功能則使用Lua語言開發,以降低開發成本。
- 簡單,自動化。盡最大的努力避免人為操作的加入,最好做到零配置,一個配置可拷貝到各個節點使用。
- 少依賴。盡量在Nginx基礎上完成所有工作,包括資料記錄。因為少一個軟體的配置,對運維人員就是少一分工作,也少一個出現故障的可能。如果一個子產品要裝個MySQL類的軟體配套才能工作,是不可接受的。裝了MySQL,可能會因MySQL查詢壓力的問題要裝個Redis或memcached中間緩存軟體,并且MySQL還有軟體崩潰或網絡不通等意外,為此再做兩台伺服器進行熱備?看上去隻是多裝一個軟體,但為了配套,也許還有其他的軟體也得加進來,是以萬不得以就不能有過多依賴。
與傳統CDN系統的差別:
實踐總結:
雖然UpCDN系統的業務功能較傳統的CDN系統複雜,多了好幾個子產品運算,但對通路請求的處理耗時并沒産生影響,可忽略。并且使用到SSD固态硬碟來提供熱門内容的緩存服務,整體的服務處理能力還大大增加(前後對比,使用SSD固态硬碟後單台伺服器的服務能力提升了1倍多)。
整體系統分為三層,可充分降低資料中心的通路壓力。我們還在第二層中間結點部署有圖檔處理伺服器和音頻處理伺服器的叢集,把一部分資料中心工作向外擴,進一步減輕壓力并能提高整體系統性能。
- UpCDN系統上線正式投入服務到今已穩定運作3年多,較我們早年部署的CDN系統有了很大提升。未來我們還将繼續完善UpCDN系統,在自動化管理方面加大研發力度(這将涉及到伺服器硬體、系統環境和軟體部署等方面,需制定軟硬體标準和完善的節點監控系統),以實作一個智能化、自動維護的CDN系統。