1 介紹現(xiàn)在很多的網(wǎng)站上都會用到大量的圖片,而圖片是網(wǎng)頁傳輸中占主要的數(shù)據(jù)量,也是影響網(wǎng)站性能的主要因素。因此很多網(wǎng)站都會將圖片存儲從網(wǎng)站中分離出來,另外架構(gòu)一個或多個服務(wù)器來存儲圖片,將圖片放到一個虛擬目錄中,而網(wǎng)頁上的圖片都用一個URL地址來指向這些服務(wù)器上的圖片的地址,這樣的話網(wǎng)站的性能就明顯提高了,圖片服務(wù)器(ImageServer)的概念也就產(chǎn)生了。 1.1 圖片服務(wù)器的優(yōu)勢
1, 分擔(dān)Web服務(wù)器的I/O負(fù)載-將耗費資源的圖片服務(wù)分離出來,提高服務(wù)器的性能和穩(wěn)定性。 2, 能夠?qū)iT對圖片服務(wù)器進(jìn)行優(yōu)化-為圖片服務(wù)設(shè)置有針對性的緩存方案,減少帶寬成本,提高訪問速度。 3, 提高網(wǎng)站的可擴展性-通過增加圖片服務(wù)器,提高圖片吞吐能力。
1.2 圖片服務(wù)器的注意事項1, 選擇適合圖片存儲的物理介質(zhì)和文件系統(tǒng) 2, 使用物理上獨立的服務(wù)器 3, 如果擁有多臺圖片服務(wù)器,要考慮服務(wù)器之間的圖片同步問題 4, 使用獨立域名 5, 制定合理的緩存策略 6, 使用圖片處理模塊對用戶上傳的圖片進(jìn)行再加工 1.3 圖片服務(wù)器的架構(gòu)圖片是網(wǎng)站中必不可少的一個組成部分,隨著網(wǎng)站的不斷發(fā)展,對圖片的處理也將隨著訪問的增長,圖片的增加提出不斷改進(jìn)的需求, 網(wǎng)站初期,所有的一切都從簡圖片所存在的位置通常會在站點下的Images文件夾。 隨著訪問的增加,IIS壓力的增大,開始做拆分,將圖片文件夾作為單獨站點提取出來如http://images.***.com/(可能根據(jù)需要會拆分成多個圖片服務(wù)器,與具體業(yè)務(wù)環(huán)境相關(guān)),拆分之后很好的將單個IIS應(yīng)用池的壓力分擔(dān)到2個乃至多個上,大大提高訪問瓶頸。隨著訪問的進(jìn)一步增加,服務(wù)器壓力已經(jīng)無法支撐,這時我們需要將圖片站點作為獨立服務(wù)器存在。在訪問圖片的過程中,我們可能會面臨一個圖片有多個圖片尺寸的需求,前期我們通常會在保存頁面的過程中保存我們需要的各個尺寸圖片,但隨著所需尺寸的不同,保存圖片時需要的尺寸越來越多,這時我們?nèi)绾螒?yīng)對? IIS服務(wù)器的并發(fā)訪問意味著隨著用戶的進(jìn)一步增加,我們單臺圖片服務(wù)器已經(jīng)不足以應(yīng)對了,此時我們?nèi)绾芜M(jìn)一步擴展?
如上圖所示,我們此時可針對這兩個問題做出統(tǒng)一解決方案,在前端添加squid緩存服務(wù)器,添加一臺或者多臺動態(tài)切圖服務(wù)器。Squid或者Nginx代理緩存服務(wù)器能夠極大的提升圖片系統(tǒng)的并發(fā)訪問,使系統(tǒng)突破現(xiàn)有限制。動態(tài)切圖服務(wù)器主要的作用是針對不同尺寸的圖片訪問調(diào)取原圖臨時生成符合需求的圖片并返回。原圖的存儲區(qū)可以與圖片服務(wù)放在一起,也可以講圖片放于單獨的服務(wù)器上。 在此種結(jié)構(gòu)中,并發(fā)的最大訪問限制將是squid或者其他代理服務(wù)器的系統(tǒng)瓶頸,當(dāng)切圖服務(wù)壓力增大時,只需添加相應(yīng)切圖服務(wù)器即可,圖片存儲區(qū)的增長也可通過添加硬盤或者服務(wù)器進(jìn)行解決。 如果您的站點訪問量還在進(jìn)一步增長,squid的訪問瓶頸即將被突破,這時我們又該如何應(yīng)對呢?
如上圖所示,采用多臺Squid或Nginx服務(wù)器,在前端添加F5或LVS負(fù)載均衡(同時還可開啟緩存功能)。此時將極大提升訪問的并發(fā)量,可以根據(jù)情況隨時調(diào)配服務(wù)器。當(dāng)然此時也存在一定的瑕疵,那就是可能在多臺Squid上存在同一張圖片,因為訪問圖片時可能第一次分到squid1,在F5過期后第二次訪問到squid2或者別的,當(dāng)然相對并發(fā)問題的解決,此種少量的冗余完全在我們的允許范圍之內(nèi)。在做了這許多的工作后,如果條件允許對圖片服務(wù)器做下CDN,那將會對您站點的圖片訪問質(zhì)量有更大的提升。
1.4 圖片存儲架構(gòu)1.4.1 部署獨立圖片服務(wù)器的必要性我們知道,無論對于Apache還是IIS,圖片始終是最消耗系統(tǒng)資源的,如果將圖片服務(wù)和應(yīng)用服務(wù)放在同一個服務(wù)器的話,應(yīng)用服務(wù)器很容易會因為圖片的高I/O負(fù)載而崩潰,因此對于有些大型網(wǎng)站項目,我們有必要將圖片服務(wù)器和應(yīng)用服務(wù)器分離。部署獨立的圖片服務(wù)器(甚至是服務(wù)器集群)是大型網(wǎng)站圖片存儲解決方案中最基礎(chǔ)的,因為有了獨立的圖片服務(wù)器后,我們才能對圖片服務(wù)器做更有針對性的性能優(yōu)化,比如從硬件角度說,圖片服務(wù)器可以配置高端的硬盤,7200轉(zhuǎn)的換成15000轉(zhuǎn)的,而CPU卻只要一般就可以了;從軟件角度說,可以為圖片服務(wù)器配置特殊的文件系統(tǒng)來滿足對圖片的I/O請求,如淘寶的TFS,就很好地解決了大規(guī)模小圖片文件帶來的I/O噩夢,同時,我們也可以采用nginx、squid來代理圖片請求等等。
1.4.2 采用獨立域名注意,這里是指獨立域名,不是子域哦,比如www.圖片服務(wù)器用了suyeimg.com的域名,而不是用二級域名img.,這是為什么呢?個人覺得原因主要有以下幾點: 1、同一域名下瀏覽器的并發(fā)連接數(shù)有限制,一般在2 - 6之間,下圖列舉了各個瀏覽器的并發(fā)連接數(shù)(下圖供參考)
這樣,我們?nèi)绻o圖片服務(wù)器配置獨立的域名,那么在一個頁面中加載圖片時,就可以突破瀏覽器連接數(shù)的限制,理論上,增加一個獨立域名,并發(fā)連接數(shù)加倍。 2、由于cookie的原因,對緩存不利 比如有一張圖片http://www./img/xx.gif,那么當(dāng)我們向它發(fā)起請求的時候,會帶上www.域名下的cookie,由于大部分web cache都只緩存不帶cookie的請求,這樣就導(dǎo)致每次的圖片請求都不能命中cache,而仍舊要去原始服務(wù)器獲取圖片,導(dǎo)致圖片緩存意義不大。所以,還是給單獨搞一個圖片獨立域名吧,當(dāng)然,不只是圖片,css和js文件也可以參照這個思路來搞。 3、方便CDN同步
1.4.3 圖片服務(wù)器分離后,如何進(jìn)行圖片上傳和圖片同步當(dāng)然任何事物都具有兩面性,圖片服務(wù)器分離固然提升了圖片訪問的效率,大大緩解了服務(wù)器因圖片造成的I/O瓶頸,但是分離以后圖片的上傳和同步就成了一個大問題了。下面就我個人的想法談?wù)剮追N解決方案。 1、NFS共享方式 如果你不想在每臺圖片服務(wù)器同步所有圖片,那NFS共享是最簡單也最實用的方式。NFS是個分布式的客戶機/服務(wù)器文件系統(tǒng),NFS的實質(zhì)在于用戶間計算機的共享,用戶可以聯(lián)結(jié)到共享計算機并象訪問本地硬盤一樣訪問共享計算機上的文件。 具體實現(xiàn)思路是:web服務(wù)器通過nfs掛載多臺圖片服務(wù)器export出來的目錄,用戶先將圖片上傳到web服務(wù)器,然后將上傳的圖片通過程序拷貝到這個mount目錄中去,這樣那幾臺圖片服務(wù)器就也能訪問到剛上傳的圖片了(注意,只是共享了,并沒有真正拷貝到圖片服務(wù)器)。再給那幾臺圖片服務(wù)器綁定獨立域名,于是瀏覽器端就可以用單獨的域名來訪問圖片了。這種方式基本不會有因同步造成的延時,但需要依賴nfs,nfs掛掉會影響web服務(wù)器。如下圖 至于如何配置nfs,大家google一下,或者看一下這篇文章,是在Linux下配置NFS的http://blog.csdn.net/lixinso/article/details/6639643 2、利用FTP同步 和上面nfs不一樣的是,用戶上傳完圖片后是利用ftp同步到各個圖片服務(wù)器的,php、java、asp.net基本上都能操作ftp。這樣的話每個圖片服務(wù)器就都保存一份圖片的副本,也起到了備份的作用。但是缺點是將圖片ftp到服務(wù)器比較耗時,如果異步去同步的話又會有延時,不過一般的小圖片文件也還好了。
2 圖片服務(wù)器的URL HASH架構(gòu)剖析2.1 什么是url hash 架構(gòu)url hash架構(gòu)對url進(jìn)行一次hash算法,然后通過hash結(jié)果找到對應(yīng)的服務(wù)器。因為針對單一個url的hash結(jié)果是一樣的,所以理論上這個url會被永久分配到固定的一臺服務(wù)器上。另外因為經(jīng)過了hash算法,所以分配url就很均勻,同時訪問量也可以達(dá)到均衡。
2.2 為什么要用url hash架構(gòu)1, 圖片服務(wù)器的特點一是訪問量很大,二是容量也很大,通過簡單的負(fù)載均衡,可以解決訪問量大的問題,但是容量的問題并沒有改善。所以會造成容災(zāi)問題。 2, 容災(zāi)問題:系統(tǒng)某個時間段被訪問的數(shù)據(jù)嚴(yán)重超出緩存集群中最小單機的容納容量就會造成容災(zāi),容災(zāi)會使大量單一鏈接穿透,直接對后臺的IO性能影響很大。 3, 雖然可以通過增加緩存容量的配置來解決容災(zāi)問題,但是內(nèi)存總是有限的,為每一臺機器增加超大內(nèi)存成本上也開銷很大,另外在squid中也不宜配置很大的磁盤緩存,否則squid中的hash表會很大,性能很差。 4, 通過hash架構(gòu),可以充分利用緩存集群的內(nèi)存,容災(zāi)問題就不再取決于緩存集群中最小單機的容納容量,而是緩存集群中所有機器的容納容量之和。 2.3 各種url hash架構(gòu)1)基于dns的hash架構(gòu)。 2)基于nginx的自動hash架構(gòu)。 3)基于nginx的手動hash架構(gòu)。
2.3.1 基于dns的hash架構(gòu)dns的hash架構(gòu)圖
dns的hash架構(gòu)說明這個架構(gòu)適合面向用戶的圖片系統(tǒng),比如論壇、相冊、博客中的圖片上傳。這樣它才能夠保證文件名有一致的規(guī)范。 這個架構(gòu)圖分了36個域名,圖片文件名是用md5值起的,在md5值中取一位字母就可以表明它是在哪個域名里,域名就對應(yīng)了機器,上傳分發(fā)的時候也是根據(jù)此字母來分發(fā)。
dns的hash架構(gòu)的優(yōu)缺點優(yōu)點: 1)使用了dns分流,成本較低,而且dns性能高,不用維護(hù)。 2)可突破IE默認(rèn)每主機2個線程的限制。 缺點: 1)可用性方面,如果有一臺機器宕機,則指向這臺機器的請求無法讀取。 2)分流方面,只能全部同步,成本較高 3)只適用于面向用戶的系統(tǒng)
2.3.2 基于nginx的自動手動hash架構(gòu)nginx的自動hash架構(gòu)圖
nginx的自動hash架構(gòu)說明1, 這是一種新的緩存架構(gòu),由nginx作為最前端,代理到緩存機器。 2, nginx后面是緩存組,由nginx經(jīng)過url hash后將請求分到緩存機器。 3, 這個架構(gòu)方便純squid緩存升級,可以在squid的機器上加裝nginx。 4, nginx有緩存的功能,可以將一些訪問量特大的鏈接直接緩存在nginx上,就不用經(jīng)過多一次代理的請求。比如favicon.ico和網(wǎng)站的logo。 nginx的自動hash架構(gòu)優(yōu)缺點優(yōu)點 1)高性能 2)使用方便,后臺是什么樣關(guān)系不大 3)有很高的可用性 4)緩存架構(gòu),分流方便 5)可直接在nginx代理緩存部分鏈接 缺點 url分流可控性弱,增減緩存機器都會引起緩存重新分配,意味著緩存全部失效。
nginx的手動hash架構(gòu)說明1,這個架構(gòu)圖和自動hash的架構(gòu)是一樣的,唯一有差別的是hash算法的變化,自動hash是用nginx upstream hash模塊自帶的hash算法來實現(xiàn)分流,這個手動架構(gòu)是自己設(shè)計一個算法來實現(xiàn)。 2,算法設(shè)計思路是從url中取一個字符來作分流依據(jù),比如定義鏈接的倒數(shù)第10個字符來分流,同樣可以分配得很均勻。 3,手動架構(gòu)可以避免自動架構(gòu)中增減機器帶來的緩存失效問題,另外可以精確知道一個鏈接到底存在哪臺緩存上。
nginx的手動hash架構(gòu)優(yōu)缺點優(yōu)點 1)基本可以繼承自動架構(gòu)的優(yōu)點 2)避免增減機器的問題 3)精確知道鏈接存儲在哪臺緩存上 缺點 配置較復(fù)雜,要分配均勻配置不易。
采用Hash架構(gòu)對bbs架構(gòu)優(yōu)化
1,先前講的bbs架構(gòu)采用的是lvs+squid作為前端,這樣的話squidclient更新緩存時需要更新所有的squid,這個效率很低下,使用hash架構(gòu)就可以使squidclient每次只需要清理一臺squid,效率大為提升。 2,推薦的是使用nginx手動hash架構(gòu),它可以精確知道鏈接會存在哪臺機器上,這樣就可以配置精確的備份機器。
3 nginx圖片服務(wù)器的架構(gòu)方案圖片服務(wù)通常數(shù)據(jù)容量較大,而且訪問也頻繁,鑒于此,圖片服務(wù)就會有兩種問題,一是存儲問題,二是訪問量問題。
3.1 擬定一個存儲目錄規(guī)則在現(xiàn)有的/a/b/abcde.jpg這樣的hash方式下多加一個日期的目錄變成:/200810/16/a/b/abcde.jpg或者/2008/10/16/a/b/abcde.jpg。按日期制定這個目錄規(guī)則后,就可以按年月來拆機器了。 3.2 分機器,分硬盤按之前的計劃,分成兩個組,一組服務(wù)器用lvs做負(fù)載均衡負(fù)責(zé)新圖片;另一組服務(wù)器做舊圖片訪問和備份。新圖機器找?guī)着_好點的服務(wù)器,SCSI硬盤;舊圖機 器沒太大要求,PC機就行,找夠硬盤就可以,現(xiàn)在IDE的1T硬盤也不太貴,最好再搭個raid就省事了,最主要是這些機器要多。如下圖:
說明一下:
|
|