來源:https://www.cnblogs.com/dinglang/p/4608915.html
在主流的Web站點中扶叉,圖片往往是不可或缺的頁面元素,尤其在大型網(wǎng)站中帕膜,幾乎都將面臨“海量圖片資源”的存儲枣氧、訪問等相關技術問題。在針對圖片服務器的架構擴展中垮刹,也會歷經(jīng)很多曲折甚至是血淚教訓达吞,尤其是早期規(guī)劃不足,造成后期架構上很難兼容和擴展危纫。
本文將以一個真實垂直門戶網(wǎng)站的發(fā)展歷程宗挥,向大家娓娓道來。
構建在Windows平臺之上的網(wǎng)站种蝶,往往會被業(yè)內眾多技術認為很“保守”契耿,甚至會有點。很大部分原因螃征,是由于微軟技術體系的封閉和部分技術人員的短視造成的(當然搪桂,主要還是人的問題)。由于長期缺乏開源支持盯滚,所以很多人只能“閉門造車”踢械,這樣很容易形成思維局限性和短板。以圖片服務器為例子魄藕,如果前期沒有容量規(guī)劃和可擴展的設計内列,那么隨著圖片文件的不斷增多和訪問量的上升,由于在性能背率、容錯/容災话瞧、擴展性等方面的設計不足,后續(xù)將會給開發(fā)寝姿、運維工作帶來很多問題交排,嚴重時甚至會影響到網(wǎng)站業(yè)務正常運作和互聯(lián)網(wǎng)公司的發(fā)展(這絕不是在危言聳聽)。
很多公司之所以選擇Windows(.NET)平臺來構建網(wǎng)站和圖片服務器饵筑,很大部分由創(chuàng)始團隊的技術背景決定的埃篓,早期的技術人員可能更熟悉.NET,或者團隊的負責人認為Windows/.NET的易用性根资、“短平快”的開發(fā)模式架专、人才成本等方面都比較符合創(chuàng)業(yè)初期的團隊同窘,自然就選擇了Windows。后期業(yè)務發(fā)展到一定規(guī)模胶征,也很難輕易將整體架構遷移到其它開源平臺上了塞椎。
當然,對于構建大規(guī)木Φ停互聯(lián)網(wǎng)案狠,更建議首選開源架構,因為有很多成熟的案例和開源生態(tài)的支持(也會有很多坑钱雷,就看是你自己最先去踩坑骂铁,還是在別人踩了修復之后你再用),避免重復造輪子和支出高額授權費用罩抗。對于遷移難度較大的應用拉庵,個人比較推薦Linux、Mono套蒂、Jexus钞支、Mysql、Memcahed操刀、Redis……混搭的架構烁挟,同樣能支撐具有高并發(fā)訪問和大數(shù)據(jù)量等特點的互聯(lián)網(wǎng)應用。
一骨坑、單機時代的圖片服務器架構(集中式)
初創(chuàng)時期由于時間緊迫撼嗓,開發(fā)人員水平也很有限等原因。所以通常就直接在website文件所在的目錄下欢唾,建立1個upload子目錄且警,用于保存用戶上傳的圖片文件。如果按業(yè)務再細分礁遣,可以在upload目錄下再建立不同的子目錄來區(qū)分斑芜。例如:upload\QA,upload\Face等。
在數(shù)據(jù)庫表中保存的也是”upload/qa/test.jpg”這類相對路徑祟霍。
用戶的訪問方式如下:
http://www.yourdomain.com/upload/qa/test.jpg
程序上傳和寫入方式:
程序員A通過在web.config中配置物理目錄D:\Web\yourdomain\upload? 然后通過stream的方式寫入文件杏头;
程序員B通過Server.MapPath等方式,根據(jù)相對路徑獲取物理目錄? 然后也通過stream的方式寫入文件
優(yōu)點:實現(xiàn)起來最簡單浅碾,無需任何復雜技術,就能成功將用戶上傳的文件寫入指定目錄续语。保存數(shù)據(jù)庫記錄和訪問起來倒是也很方便垂谢。
缺點:上傳方式混亂,嚴重不利于網(wǎng)站的擴展疮茄。
針對上述最原始的架構滥朱,主要面臨著如下問題:
1根暑、隨著upload目錄中文件越來越多,所在分區(qū)(例如D盤)如果出現(xiàn)容量不足徙邻,則很難擴容排嫌。只能停機后更換更大容量的存儲設備,再將舊數(shù)據(jù)導入缰犁;
2淳地、在部署新版本(部署新版本前通過需要備份)和日常備份website文件的時候,需要同時操作upload目錄中的文件帅容,如果考慮到訪問量上升颇象,后邊部署由多臺Web服務器組成的負載均衡集群,集群節(jié)點之間如果做好文件實時同步將是個難題并徘。
二遣钳、集群時代的圖片服務器架構(實時同步)
在website站點下面,新建一個名為upload的虛擬目錄麦乞,由于虛擬目錄的靈活性蕴茴,能在一定程度上取代物理目錄,并兼容原有的圖片上傳和訪問方式姐直。用戶的訪問方式依然是:
http://www.yourdomain.com/upload/qa/test.jpg
優(yōu)點:配置更加靈活倦淀,也能兼容老版本的上傳和訪問方式。
因為虛擬目錄简肴,可以指向本地任意盤符下的任意目錄晃听。這樣一來,還可以通過接入外置存儲砰识,來進行單機的容量擴展能扒。
缺點:部署成由多臺Web服務器組成的集群,各個Web服務器(集群節(jié)點)之間(虛擬目錄下的)需要實時的去同步文件辫狼,由于同步效率和實時性的限制初斑,很難保證某一時刻各節(jié)點上文件是完全一致的。
基本架構如下圖所示:
從上圖可看出膨处,整個Web服務器架構已經(jīng)具備“可擴展见秤、高可用”了,主要問題和瓶頸都集中在多臺服務器之間的文件同步上真椿。
上述架構中只能在這幾臺Web服務器上互相“增量同步”鹃答,這樣一來,就不支持文件的“刪除突硝、更新”操作的同步了测摔。
早期的想法是,在應用程序層面做控制,當用戶請求在web1服務器進行上傳寫入的同時锋八,也同步去調用其它web服務器上的上傳接口浙于,這顯然是得不償失的嗅绰。所以我們選擇使用Rsync類的軟件來做定時文件同步的缚去,從而省去了“重復造輪子”的成本,也降低了風險性无蜂。
同步操作里面紊服,一般有比較經(jīng)典的兩種模型檀轨,即推拉模型:所謂“拉”,就是指輪詢地去獲取更新围苫,所謂推裤园,就是發(fā)生更改后主動的“推”給其它機器。當然剂府,也可以采用加高級的事件通知機制來完成此類動作拧揽。
在高并發(fā)寫入的場景中,同步都會出現(xiàn)效率和實時性問題腺占,而且大量文件同步也是很消耗系統(tǒng)和帶寬資源的(跨網(wǎng)段則更明顯)淤袜。??
三、集群時代的圖片服務器架構改進(共享存儲)
沿用虛擬目錄的方式衰伯,通過UNC(網(wǎng)絡路徑)的方式實現(xiàn)共享存儲(將upload虛擬目錄指向UNC)
用戶的訪問方式1:
http://www.yourdomain.com/upload/qa/test.jpg
用戶的訪問方式2(可以配置獨立域名):
http://img.yourdomain.com/upload/qa/test.jpg
支持UNC所在server上配置獨立域名指向铡羡,并配置輕量級的web服務器,來實現(xiàn)獨立圖片服務器意鲸。
優(yōu)點: 通過UNC(網(wǎng)絡路徑)的方式來進行讀寫操作烦周,可以避免多服務器之間同步相關的問題。相對來講很靈活怎顾,也支持擴容/擴展读慎。支持配置成獨立圖片服務器和域名訪問,也完整兼容舊版本的訪問規(guī)則槐雾。? ?
缺點 :但是UNC配置有些繁瑣夭委,而且會造成一定的(讀寫和安全)性能損失∧记浚可能會出現(xiàn)“單點故障”株灸。如果存儲級別沒有raid或者更高級的災備措施,還會造成數(shù)據(jù)丟失擎值。
基本架構如下圖所示:
在早期的很多基于Linux開源架構的網(wǎng)站中慌烧,如果不想同步圖片,可能會利用NFS來實現(xiàn)鸠儿。事實證明屹蚊,NFS在高并發(fā)讀寫和海量存儲方面,效率上存在一定問題,并非最佳的選擇淑翼,所以大部分互聯(lián)網(wǎng)公司都不會使用NFS來實現(xiàn)此類應用。當然品追,也可以通過Windows自帶的DFS來實現(xiàn)玄括,缺點是“配置復雜,效率未知肉瓦,而且缺乏資料大量的實際案例”遭京。另外,也有一些公司采用FTP或Samba來實現(xiàn)泞莉。
上面提到的幾種架構哪雕,在上傳/下載操作時,都經(jīng)過了Web服務器(雖然共享存儲的這種架構鲫趁,也可以配置獨立域名和站點來提供圖片訪問斯嚎,但上傳寫入仍然得經(jīng)過Web服務器上的應用程序來處理),這對Web服務器來講無疑是造成巨大的壓力挨厚。所以堡僻,更建議使用獨立的圖片服務器和獨立的域名,來提供用戶圖片的上傳和訪問疫剃。
四钉疫、獨立圖片服務器/獨立域名的好處
1、圖片訪問是很消耗服務器資源的(因為會涉及到操作系統(tǒng)的上下文切換和磁盤I/O操作)巢价。分離出來后牲阁,Web/App服務器可以更專注發(fā)揮動態(tài)處理的能力。
2壤躲、獨立存儲城菊,更方便做擴容、容災和數(shù)據(jù)遷移柒爵。
3役电、瀏覽器(相同域名下的)并發(fā)策略限制,性能損失棉胀。
4法瑟、訪問圖片時,請求信息中總帶cookie信息唁奢,也會造成性能損失霎挟。
5、方便做圖片訪問請求的負載均衡麻掸,方便應用各種緩存策略(HTTP Header酥夭、Proxy Cache等),也更加方便遷移到CDN。
......
我們可以使用Lighttpd或者Nginx等輕量級的web服務器來架構獨立圖片服務器熬北。
五疙描、當前的圖片服務器架構(分布式文件系統(tǒng)+CDN)
在構建當前的圖片服務器架構之前,可以先徹底撇開web服務器讶隐,直接配置單獨的圖片服務器/域名起胰。但面臨如下的問題:
1、舊圖片數(shù)據(jù)怎么辦巫延?能否繼續(xù)兼容舊圖片路徑訪問規(guī)則效五?
2、獨立的圖片服務器上需要提供單獨的上傳寫入的接口(服務API對外發(fā)布)炉峰,安全問題如何保證畏妖?
3、同理疼阔,假如有多臺獨立圖片服務器戒劫,是使用可擴展的共享存儲方案,還是采用實時同步機制婆廊?
直到應用級別的(非系統(tǒng)級) DFS(例如FastDFS HDFS MogileFs MooseFS谱仪、TFS)的流行,簡化了這個問題:執(zhí)行冗余備份否彩、支持自動同步疯攒、支持線性擴展、支持主流語言的客戶端api上傳/下載/刪除等操作列荔,部分支持文件索引敬尺,部分支持提供Web的方式來訪問。
考慮到各DFS的特點贴浙,客戶端API語言支持情況(需要支持C#)砂吞,文檔和案例,以及社區(qū)的支持度崎溃,我們最終選擇了FastDFS來部署
唯一的問題是:可能會不兼容舊版本的訪問規(guī)則!
如果將舊圖片一次性導入FastDFS蜻直,但由于舊圖片訪問路徑分布存儲在不同業(yè)務數(shù)據(jù)庫的各個表中,整體更新起來也十分困難袁串,所以必須得兼容舊版本的訪問規(guī)則概而。架構升級往往比做全新架構更有難度,就是因為還要兼容之前版本的問題囱修。(給飛機在空中換引擎可比造架飛機難得多)
六赎瑰、解決方案如下:
首先,關閉舊版本上傳入口(避免繼續(xù)使用導致數(shù)據(jù)不一致)破镰。將舊圖片數(shù)據(jù)通過rsync工具一次性遷移到獨立的圖片服務器上(即下圖中描述的Old Image Server)餐曼。在最前端(七層代理压储,如Haproxy、Nginx)用ACL(訪問規(guī)則控制)源譬,將舊圖片對應URL規(guī)則的請求(正則)匹配到集惋,然后將請求直接轉發(fā)指定的web 服務器列表,在該列表中的服務器上配置好提供圖片(以Web方式)訪問的站點踩娘,并加入緩存策略芋膘。這樣實現(xiàn)舊圖片服務器的分離和緩存,兼容了舊圖片的訪問規(guī)則并提升舊圖片訪問效率,也避免了實時同步所帶來的問題霸饲。
整體架構如圖:
基于FastDFS的獨立圖片服務器集群架構,雖然已經(jīng)非常的成熟臂拓,但是由于國內“南北互聯(lián)”和IDC帶寬成本等問題(圖片是非常消耗流量的)厚脉,我們最終還是選擇了商用的CDN技術,實現(xiàn)起來也非常容易胶惰,原理其實也很簡單傻工,我這里只做個簡單的介紹:
將img域名cname到CDN廠商指定的域名上,用戶請求訪問圖片時孵滞,則由CDN廠商提供智能DNS解析中捆,將最近的(當然也可能有其它更復雜的策略,例如負載情況坊饶、健康狀態(tài)等)服務節(jié)點地址返回給用戶泄伪,用戶請求到達指定的服務器節(jié)點上,該節(jié)點上提供了類似Squid/Vanish的代理緩存服務匿级,如果是第一次請求該路徑蟋滴,則會從源站獲取圖片資源返回客戶端瀏覽器,如果緩存中存在痘绎,則直接從緩存中獲取并返回給客戶端瀏覽器津函,完成請求/響應過程。
由于采用了商用CDN服務孤页,所以我們并沒有考慮用Squid/Vanish來自行構建前置代理緩存尔苦。
上面的整個集群架構,可以很方便的做橫向擴展行施,能滿足一般垂直領域中大型網(wǎng)站的圖片服務需求(當然允坚,像taobao這樣超大規(guī)模的可能另當別論)。經(jīng)測試蛾号,提供圖片訪問的單臺Nginx服務器(至強E5四核CPU屋讶、16G內存、SSD)须教,對小靜態(tài)頁面(壓縮后大概只有10kb左右的)可以扛住幾千個并發(fā)且毫無壓力皿渗。當然斩芭,由于圖片本身體積比純文本的靜態(tài)頁面大很多,提供圖片訪問的服務器的抗并發(fā)能力乐疆,往往會受限于磁盤的I/O處理能力和IDC提供的帶寬划乖。Nginx的抗并發(fā)能力還是非常強的,而且對資源占用很低挤土,尤其是處理靜態(tài)資源琴庵,似乎都不需要有過多擔心了⊙雒溃可以根據(jù)實際訪問量的需求迷殿,通過調整Nginx的參數(shù),對Linux內核做調優(yōu)咖杂,加入分級緩存策略等手段能夠做更大程度的優(yōu)化庆寺,也可以通過增加服務器或者升級服務器配置來做擴展,最直接的是通過購買更高級的存儲設備和更大的帶寬诉字,以滿足更大訪問量的需求懦尝。
值得一提的是,在“云計算”流行的當下壤圃,也推薦高速發(fā)展期間的網(wǎng)站陵霉,使用“云存儲”這樣的方案,既能幫你解決各類存儲伍绳、擴展踊挠、備災的問題,又能做好CDN加速冲杀。最重要的是止毕,價格也不貴。
總結漠趁,有關圖片服務器架構擴展扁凛,大致圍繞這些問題展開:
1、容量規(guī)劃和擴展問題闯传。
2谨朝、數(shù)據(jù)的同步、冗余和容災甥绿。
3字币、硬件設備的成本和可靠性(是普通機械硬盤,還是SSD共缕,或者更高端的存儲設備和方案)洗出。
4、文件系統(tǒng)的選擇图谷。根據(jù)文件特性(例如文件大小翩活、讀寫比例等)選擇是用ext3/4或者NFS/GFS/TFS這些開源的(分布式)文件系統(tǒng)阱洪。
5、圖片的加速訪問菠镇。采用商用CDN或者自建的代理緩存冗荸、web靜態(tài)緩存架構。
6利耍、舊圖片路徑和訪問規(guī)則的兼容性蚌本,應用程序層面的可擴展,上傳和訪問的性能和安全性等隘梨。
擴展閱讀