圖片服務架構演進

現在幾乎任何一個網站、Web App以及移動APP等應用都需要有圖片展示的功能,對於圖片功能從下至上都是很重要的。必須要具有前瞻性的規劃好圖片服務器,圖片的上傳和下載速度至關重要,當然這並不是說一上來就搞很NB的架構,至少具備一定擴展性和穩定性。雖然各種架構設計都有,在這裏我只是談談我的一些個人想法。

 

對於圖片服務器來說IO無疑是消耗資源最爲嚴重的,對於web應用來說需要將圖片服務器做一定的分離,否則很可能因爲圖片服務器的IO負載導致應用崩潰。因此尤其對於大型網站和應用來說,非常有必要將圖片服務器和應用服務器分離,構建獨立的圖片服務器集羣,構建獨立的圖片服務器其主要優勢:

1)分擔Web服務器的I/O負載-將耗費資源的圖片服務分離出來,提高服務器的性能和穩定性。

2)能夠專門對圖片服務器進行優化-爲圖片服務設置有針對性的緩存方案,減少帶寬網絡成本,提高訪問速度。

3)提高網站的可擴展性-通過增加圖片服務器,提高圖片服務吞吐能力。

 

從傳統互聯網的web1.0,歷經web2.0時代以及發展到現在的web3.0,隨着圖片存儲規模的增加,圖片服務器的架構也在逐漸發生變化,以下主要論述三個階段的圖片服務器架構演進。

 

 初始階段


在介紹初始階段的早期的小型圖片服務器架構之前,首先讓我們瞭解一下NFS技術,NFS是Network File System的縮寫,即網絡文件系統。NFS是由Sun開發並發展起來的一項用於在不同機器,不同操作系統之間通過網絡互相分享各自的文件。NFS server也可以看作是一個FILE SERVER,用於在UNIX類系統之間共享文件,可以輕鬆的掛載(mount)到一個目錄上,操作起來就像本地文件一樣的方便。

 

如果不想在每臺圖片服務器同步所有圖片,那麼NFS是最簡單的文件共享方式。NFS是個分佈式的客戶機/服務器文件系統,NFS的實質在於用戶間計算機的共享,用戶可以聯結到共享計算機並象訪問本地硬盤一樣訪問共享計算機上的文件。具體實現思路是:

 

1)所有前端web服務器都通過nfs掛載3臺圖片服務器export出來的目錄,以接收web服務器寫入的圖片。然後[圖片1]服務器掛載另外兩臺圖片服務器的export目錄到本地給apache對外提供訪問。
2) 用戶上傳圖片
用戶通過Internet訪問頁面提交上傳請求post到web服務器,web服務器處理完圖片後由web服務器拷貝到對應的mount本地目錄。
3)用戶訪問圖片
用戶訪問圖片時,通過[圖片1]這臺圖片服務器來讀取相應mount目錄裏邊的圖片。

 

以上架構存在的問題:

1)性能:現有結構過度依賴nfs,當圖片服務器的nfs服務器有問題時,可能影響到前端web服務器。NFS的問題主要是鎖的問題. 很容易造成死鎖, 只有硬件重啓才能解決。尤其當圖片達到一定的量級後,nfs會有嚴重的性能問題。
2)高可用:對外提供下載的圖片服務器只有一臺,容易出現單點故障。
3) 擴展性:圖片服務器之間的依賴過多,而且橫向擴展餘地不夠。
4) 存儲:web服務器上傳熱點不可控,造成現有圖片服務器空間佔用不均衡。
5) 安全性:nfs方式對於擁有web服務器的密碼的人來說,可以隨意修改nfs裏邊的內容,安全級別不高。

 

當然圖片服務器的圖片同步可以不採用NFS,也可以採用ftp或rsync,採用ftp這樣的話每個圖片服務器就都保存一份圖片的副本,也起到了備份的作用。但是缺點是將圖片ftp到服務器比較耗時,如果使用異步方式去同步圖片的話又會有延時,不過一般的小圖片文件也還好了。使用rsync同步,當數據文件達到一定的量級後,每次rsync掃描會耗時很久也會帶來一定的延時性。

 

 

發展階段


當網站達到一定的規模後,對圖片服務器的性能和穩定性有一定的要求後,上述NFS圖片服務架構面臨着挑戰,嚴重的依賴NFS,而且系統存在單點機器容易出現故障,需要對整體架構進行升級。於是出現了上圖圖片服務器架構,出現了分佈式的圖片存儲。

 

其實現的具體思路如下:

1)用戶上傳圖片到web服務器後,web服務器處理完圖片,然後再由前端web服務器把圖片post到到[圖片1]、[圖片2]…[圖片N]其中的一個,圖片服務器接收到post過來的圖片,然後把圖片寫入到本地磁盤並返回對應成功狀態碼。前端web服務器根據返回狀態碼決定對應操作,如果成功的話,處理生成各尺寸的縮略圖、打水印,把圖片服務器對應的ID和對應圖片路徑寫入DB數據庫。
2) 上傳控制
我們需要調節上傳時,只需要修改web服務器post到的目的圖片服務器的ID,就可以控制上傳到哪臺圖片存儲服務器,對應的圖片存儲服務器只需要安裝nginx同時提供一個python或者php服務接收並保存圖片,如果不想不想開啓python或者php服務,也可以編寫一個nginx擴展模塊。

3) 用戶訪問流程
用戶訪問頁面的時候,根據請求圖片的URL到對應圖片服務器去訪問圖片。

如: http://imgN.xxx.com/image1.jpg

 

此階段的圖片服務器架構,增加了負載均衡和分佈式圖片存儲,能夠在一定程度上解決併發訪問量高和存儲量大的問題。負載均衡在有一定財力的情況下可以考慮F5硬負載,當然也可以考慮使用開源的LVS軟負載(同時還可開啓緩存功能)。此時將極大提升訪問的併發量,可以根據情況隨時調配服務器。當然此時也存在一定的瑕疵,那就是可能在多臺Squid上存在同一張圖片,因爲訪問圖片時可能第一次分到squid1,在LVS過期後第二次訪問到squid2或者別的,當然相對併發問題的解決,此種少量的冗餘完全在我們的允許範圍之內。在該系統架構中二級緩存可以使用squid也可以考慮使用varnish或者traffic server,對於cache的開源軟件選型要考率以下幾點

 

1)性能:varnish本身的技術上優勢要高於squid,它採用了“Visual Page Cache”技術,在內存的利用上,Varnish比Squid具有優勢,它避免了Squid頻繁在內存、磁盤中交換文件,性能要比Squid高。varnish是不能cache到本地硬盤上的。還有強大的通過Varnish管理端口,可以使用正則表達式快速、批量地清除部分緩存。nginx是用第三方模塊ncache做的緩衝,其性能基本達到varnish,但在架構中nginx一般作爲反向(靜態文件現在用nginx的很多,併發能支持到2萬+)。在靜態架構中,如果前端直接面對的是cdn活着前端了4層負載的話,完全用nginx的cache就夠了。

 

2)避免文件系統式的緩存,在文件數據量非常大的情況下,文件系統的性能很差,像squid,nginx的proxy_store,proxy_cache之類的方式緩存,當緩存的量級上來後,性能將不能滿足要求。開源的traffic server直接用裸盤緩存,是一個不錯的選擇,國內大規模應用並公佈出來的主要是淘寶,並不是因爲它做的差,而是開源時間晚。Traffic Server 在 Yahoo 內部使用了超過 4 年,主要用於 CDN 服務,CDN 用於分發特定的HTTP 內容,通常是靜態的內容如圖片、JavaScript、CSS。當然使用leveldb之類的做緩存,我估計也能達到很好的效果。

 

3)穩定性:squid作爲老牌勁旅緩存,其穩定性更可靠一些,從我身邊一些使用者反饋來看varnish偶爾會出現crash的情況。Traffic Server在雅虎目前使用期間也沒有出現已知的數據損壞情況,其穩定性相對也比較可靠,對於未來我其實更期待Traffic Server在國內能夠擁有更多的用戶。

        以上圖片服務架構設計消除了早期的NFS依賴以及單點問題,時能夠均衡圖片服務器的空間,提高了圖片服務器的安全性等問題,但是又帶來一個問題是圖片服務器的橫向擴展冗餘問題。只想在普通的硬盤上存儲,首先還是要考慮一下物理硬盤的實際處理能力。是 7200 轉的還是 15000 轉的,實際表現差別就很大。至於文件系統選擇xfs、ext3、ext4還是reiserFs,需要做一些性能方面的測試,從官方的一些測試數據來看,reiserFs更適合存儲一些小圖片文件。創建文件系統的時候 Inode 問題也要加以考慮,選擇合適大小的 inode size ,因爲Linux 爲每個文件分配一個稱爲索引節點的號碼inode,可以將inode簡單理解成一個指針,它永遠指向本文件的具體存儲位置。一個文件系統允許的inode節點數是有限的,如果文件數量太多,即使每個文件都是0字節的空文件,系統最終也會因爲節點空間耗盡而不能再創建文件,因此需要在空間和速度上做取捨,構造合理的文件目錄索引。

 

 

雲存儲階段

2011年李彥宏在百度聯盟峯會上就提到過互聯網的讀圖時代已經到來,圖片服務早已成爲一個互聯網應用中佔比很大的部分,對圖片的處理能力也相應地變成企業和開發者的一項基本技能,圖片的下載和上傳速度顯得更加重要,要想處理好圖片,需要面對的三個主要問題是:大流量、高併發、海量存儲。

 

阿里雲存儲服務(OpenStorageService,簡稱OSS),是阿里雲對外提供的海量,安全,低成本,高可靠的雲存儲服務。用戶可以通過簡單的 REST接口,在任何時間、任何地點上傳和下載數據,也可以使用WEB頁面對數據進行管理。同時,OSS提供Java、Python、PHP SDK,簡化用戶的編程。基於OSS,用戶可以搭建出各種多媒體分享網站、網盤、個人企業數據備份等基於大規模數據的服務。在以下圖片雲存儲主要以阿里雲的雲存儲OSS爲切入點介紹,上圖爲OSS雲存儲的簡單架構示意圖。

 

真正意義上的“雲存儲”,不是存儲而是提供雲服務,使用雲存儲服務的主要優勢有以下幾點:

1)用戶無需瞭解存儲設備的類型、接口、存儲介質等。

2)無需關心數據的存儲路徑。

3)無需對存儲設備進行管理、維護。

4)無需考慮數據備份和容災

5)簡單接入雲存儲,盡情享受存儲服務。

 

 

架構模塊組成


1)KV Engine

OSS中的Object源信息和數據文件都是存放在KV Engine上。在6.15的版本,V Engine將使用0.8.6版本,並使用爲OSS提供的OSSFileClient。

 

2)Quota

此模塊記錄了Bucket和用戶的對應關係,和以分鐘爲單位的Bucket資源使用情況。Quota還將提供HTTP接口供Boss系統查詢。

 

3)安全模塊

安全模塊主要記錄User對應的ID和Key,並提供OSS訪問的用戶驗證功能。

 

OSS術語名詞彙

 

1 )Access Key ID & Access Key Secret (API密鑰)
用戶註冊OSS時,系統會給用戶分配一對Access Key ID & Access Key Secret,稱爲ID對,用於標識用戶,爲訪問OSS做簽名驗證。

 

2) Service
OSS提供給用戶的虛擬存儲空間,在這個虛擬空間中,每個用戶可擁有一個到多個Bucket。

 

3) Bucket
Bucket是OSS上的命名空間;Bucket名在整個OSS中具有全局唯一性,且不能修改;存儲在OSS上的每個Object必須都包含在某個Bucket中。一個應用,例如圖片分享網站,可以對應一個或多個Bucket。一個用戶最多可創建10個Bucket,但每個Bucket中存放的Object的數量和大小總和沒有限制,用戶不需要考慮數據的可擴展性。

4) Object
在OSS中,用戶的每個文件都是一個Object,每個文件需小於5TB。Object包含key、data和user meta。其中,key是Object的名字;data是Object的數據;user meta是用戶對該object的描述。
其使用方式非常簡單,如下爲java sdk:

OSSClient ossClient = new OSSClient(accessKeyId,accessKeySecret);

PutObjectResult result = ossClient.putObject(bucketname,          bucketKey, inStream,  new ObjectMetadata());

執行以上代碼即可將圖片流上傳至OSS服務器上。

圖片的訪問方式也非常簡單其url爲:http://bucketname.oss.aliyuncs.com/bucketKey

 

 

分佈式文件系統

用分佈式存儲有幾個好處,分佈式能自動提供冗餘,不需要我們去備份,擔心數據安全,在文件數量特別大的情況下,備份是一件很痛苦的事情,rsync掃一次可能是就是好幾個小時,還有一點就是分佈式存儲動態擴容方便。當然在國內的其他一些文件系統裏,TFS(http://code.taobao.org/p/tfs/src/)和FASTDFS也有一些用戶,但是TFS的優勢更是針對一些小文件存儲,主要是淘寶在用。另外FASTDFS在併發高於300寫入的情況下出現性能問題,穩定性不夠友好。OSS存儲使用的是阿里雲基於飛天5k平臺自主研發的高可用,高可靠的分佈式文件系統盤古。分佈式文件系統盤古和Google的GFS類似,盤古的架構是Master-Slave主從架構,Master負責元數據管理,Sliave叫做Chunk Server,負責讀寫請求。其中Master是基於Paxos的多Master架構,一個Master死了之後,另外一個Master可以很快接過去,基本能夠做到故障恢復在一分鐘以內 。文件是按照分片存放,每個會分三個副本,放在不同的機架上,最後提供端到端的數據校驗。

 

 

HAPROXY負載均衡

基於haproxy的自動hash架構 ,這是一種新的緩存架構,由nginx作爲最前端,代理到緩存機器。 nginx後面是緩存組,由nginx經過url hash後將請求分到緩存機器。
這個架構方便純squid緩存升級,可以在squid的機器上加裝nginx。 nginx有緩存的功能,可以將一些訪問量特大的鏈接直接緩存在nginx上,就不用經過多一次代理的請求,能夠保證圖片服務器的高可用、高性能。比如favicon.ico和網站的logo。 負載均衡負責OSS所有的請求的負載均衡,後臺的http服務器故障會自動切換,從而保證了OSS的服務不間斷。

 

 

CDN

阿里雲CDN服務是一個遍佈全國的分佈式緩存系統,能夠將網站文件(如圖片或JavaScript代碼文件)緩存到全國多個城市機房中的服務器上,當一個用戶訪問你的網站時,會就近到靠近TA的城市的服務器上獲取數據,這樣最終用戶訪問你的服務速度會非常快。

阿里雲CDN服務在全國部署超過100個節點,能提供給用戶優良的網絡加速效果。當網站業務突然爆發增長時,無需手忙腳亂地擴容網絡帶寬,使用CDN服務即可輕鬆應對。和OSS服務一樣,使用CDN,需要先在aliyun.com網站上開通CDN服務。開通後,需要在網站上的管理中心創建你的distribution(即分發頻道),每個distribution由兩個必須的部分組成:distribution ID和源站地址。

使用阿里雲OSS和CDN可以非常方便的針對每個bucket進行內容加速,因爲每個bucket對應一個獨立的二級域名,針對每個文件進行CDN刪除,簡單、經濟地解決服務的存儲和網絡問題,畢竟大多數網站或應用的存儲和網絡帶寬多半是被圖片或視頻消耗掉的。

從整個業界來看,最近這樣的面向個人用戶的雲存儲如國外的DropBox和Box.net非常受歡迎,國內的雲存儲目前比較不錯的主要有七牛雲存儲和又拍雲存儲。

 

 

上傳下載分而治之

圖片服務器的圖片下載比例遠遠高於上傳比例,業務邏輯的處理也區別明顯,上傳服器對圖片重命名,記錄入庫信息,下載服務器對圖片添加水印、修改尺寸之類的動態處理。從高可用的角度,我們能容忍部分圖片下載失敗,但絕不能有圖片上傳失敗,因爲上傳失敗,意味着數據的丟失。上傳與下載分開,能保證不會因下載的壓力影響圖片的上傳,而且還有一點,下載入口和上傳入口的負載均衡策略也有所不同。上傳需要經過Quota Server記錄用戶和圖片的關係等邏輯處理,下載的邏輯處理如果繞過了前端緩存處理,穿透後端業務邏輯處理,需要從OSS獲取圖片路徑信息。近期阿里雲會推出基於CDN就近上傳的功能,自動選擇離用戶最近的CDN節點,使得數據的上傳下載速度均得到最優化。相較傳統IDC,訪問速度提升數倍。

 

 

圖片防盜鏈處理

如果服務不允許防盜鏈,那麼訪問量會引起帶寬、服務器壓力等問題。比較通用的解決方案是在nginx或者squid反向代理軟件上添加refer ACL判斷,OSS也提供了基於refer的防盜鏈技術。當然OSS也提供了更爲高級的URL簽名防盜鏈,其其實現思路如下:

 

首先,確認自己的bucket權限是private,即這個bucket的所有請求必須在簽名認證通過後才被認爲是合法的。然後根據操作類型、要訪問的bucket、要訪問的object以及超時時間,動態地生成一個經過簽名的URL。通過這個簽名URL,你授權的用戶就可以在該簽名URL過期時間前執行相應的操作。

 

簽名的Python代碼如下:

h=hmac.new(“OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV”, “GET\n\n\n1141889120\n/oss-example/oss-api.jpg”,sha);

urllib.quote_plus (base64.encodestring(h.digest()).strip());

 

其中method可以是PUT、GET、HEAD、DELETE中的任意一種;最後一個參數“timeout”是超時的時間,單位是秒。一個通過上面Python方法,計算得到的簽名URL爲:

http://oss-example.oss-cn-hangzhou.aliyuncs.com/oss-api.jpg?OSSAccessKeyId=44CF9590006BF252F707&Expires=1141889120&Signature=vjbyPxybdZaNmGa%2ByT272YEAiv4%3D

 

通過這種動態計算簽名URL的方法,可以有效地保護放在OSS上的數據,防止被其他人盜鏈。

 

 

圖片編輯處理API

對於在線圖片的編輯處理,GraphicsMagick(GraphicsMagick(http://www.graphicsmagick.org/))對於從事互聯網的技術人員應該不會陌生。GraphicsMagick是從 ImageMagick 5.5.2 分支出來的,但是現在他變得更穩定和優秀,GM更小更容易安裝、GM更有效率、GM的手冊非常豐富GraphicsMagick的命令與ImageMagick基本是一樣的。

 

GraphicsMagick 提供了包括裁、縮放、合成、打水印、圖像轉換、填充等非常豐富的接口API,其中的開發包SDK也非常豐富,包括了JAVA(im4java)、C、C++、Perl、PHP、Tcl、Ruby等的調用,支持超過88中圖像格式,包括重要的DPX、GIF、JPEG、JPEG-2000、PNG、PDF、PNM和TIFF,GraphicsMagick可以再絕大多數的平臺上使用,Linux、Mac、Windows都沒有問題。但是獨立開發這些圖片處理服務,對服務器的IO要求相對要高一些,而且目前這些開源的圖片處理編輯庫,相對來說還不是很穩定,筆者在使用GraphicsMagick 的時候就遇到了tomcat 進程crash情況,需要手動重啓tomcat服務。

 

阿里雲目前已經對外開放圖片處理API,包括了大多數常用處理解決方案:縮略圖、打水印、文字水印、樣式、管道等。開發者可以非常方便的使用如上圖片處理方案,希望越來越多的開發者能夠基於OSS開放出更多優秀的產品。


轉自:阿里雲產品博客

參考:

http://blog.163.com/sun_jian_zhang/blog/static/1878040412012512112347454/



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章