大型Windows平臺網站圖片服務器架構的演進

構建在Windows平臺之上的網站,往往會被業內眾多架構師認為很保守。很大部分原因,是由於微軟技術體系的封閉和部分技術人員的短視造成的。由於長期缺乏開源支持,所以隻能閉門造車,這樣很容易形成思維局限性和短板。就拿圖片服務器為例子,如果前期沒有容量規劃和可擴展的設計,那麼隨著圖片文件的不斷增多和訪問量的上升,由於在性能、容錯/容災、擴展性等方面的設計不足,後續將會給開發、運維工作帶來很多問題,嚴重時甚至會影響到網站業務正常運作和互聯網公司的發展(這絕不是在危言聳聽)。

之所以選擇Windows平臺來構建網站和圖片服務器,很大部分由創始團隊的技術背景決定的,早期的技術人員可能更熟悉.NET,或者負責人認為Windows/.NET的易用性、短平快的開發模式、人才成本等方面都比較符合創業初期的團隊,自然就選擇瞭Windows。後期業務發展到一定規模,也很難輕易將整體架構遷移到其它平臺上瞭。當然,對於構建大規模互聯網,更建議首選開源架構,因為有很多成熟的案例和開源生態的支持,避免重復造輪子和支出授權費用。對於遷移難度較大的應用,比較推薦Linux、Mono、Mysql、Memcahed混搭的架構,同樣能支撐高並發訪問和大數據量。

單機時代的圖片服務器架構(集中式)

初創時期由於時間緊迫,開發人員水平也很有限等原因。所以通常就直接在website文件所在的目錄下,建立1個upload子目錄,用於保存用戶上傳的圖片文件。如果按業務再細分,可以在upload目錄下再建立不同的子目錄來區分。例如:upload\QA,upload\Face等。

在數據庫表中保存的也是upload/qa/test.jpg這類相對路徑。

用戶的訪問方式如下:

/2015/0731/1438326331263.jpg

程序上傳和寫入方式:

程序員A通過在web.config中配置物理目錄D:\Web\yourdomain\upload 然後通過stream的方式寫入文件;

程序員B通過Server.MapPath等方式,根據相對路徑獲取物理目錄 然後也通過stream的方式寫入文件。

優點:實現起來最簡單,無需任何復雜技術,就能成功將用戶上傳的文件寫入指定目錄。保存數據庫記錄和訪問起來倒是也很方便。

缺點:上傳方式混亂,嚴重不利於網站的擴展。

針對上述最原始的架構,主要面臨著如下問題:

  1. 隨著upload目錄中文件越來越多,所在分區(例如D盤)如果出現容量不足,則很難擴容。隻能停機後更換更大容量的存儲設備,再將舊數據導入。
  2. 在部署新版本(部署新版本前通過需要備份)和日常備份website文件的時候,需要同時操作upload目錄中的文件,如果考慮到訪問量上升,後邊部署由多臺Web服務器組成的負載均衡集群,集群節點之間如果做好文件實時同步將是個難題。

集群時代的圖片服務器架構(實時同步)

在website站點下面,新建一個名為upload的虛擬目錄,由於虛擬目錄的靈活性,能在一定程度上取代物理目錄,並兼容原有的圖片上傳和訪問方式。用戶的訪問方式依然是:

/2015/0731/1438326331844.jpg

優點:配置更加靈活,也能兼容老版本的上傳和訪問方式。

因為虛擬目錄,可以指向本地任意盤符下的任意目錄。這樣一來,還可以通過接入外置存儲,來進行單機的容量擴展。

缺點:部署成由多臺Web服務器組成的集群,各個Web服務器(集群節點)之間(虛擬目錄下的)需要實時的去同步文件,由於同步效率和實時性的限制,很難保證某一時刻各節點上文件是完全一致的。

基本架構如下圖所示:

從上圖可看出,整個Web服務器架構已經具備可擴展、高可用瞭,主要問題和瓶頸都集中在多臺服務器之間的文件同步上。

上述架構中隻能在這幾臺Web服務器上互相增量同步,這樣一來,就不支持文件的刪除、更新操作的同步瞭。

早期的想法是,在應用程序層面做控制,當用戶請求在web1服務器進行上傳寫入的同時,也同步去調用其它web服務器上的上傳接口,這顯然是得不償失的。所以我們選擇使用Rsync類的軟件來做定時文件同步的,從而省去瞭重復造輪子的成本,也降低瞭風險性。

同步操作裡面,一般有比較經典的兩種模型,即推拉模型:所謂拉,就是指輪詢地去獲取更新,所謂推,就是發生更改後主動的推給其它機器。當然,也可以采用加高級的事件通知機制來完成此類動作。

在高並發寫入的場景中,同步都會出現效率和實時性問題,而且大量文件同步也是很消耗系統和帶寬資源的(跨網段則更明顯)。