分散式圖片系統

java06051515發表於2020-02-25

概述


隨著公司的快速發展,公司對外服務的系統在展現形式方面出現了多樣化,目前包括Web端和手機端,不同的展現形式由於裝置的多樣性和裝置對網路的依賴程度的不同,在對圖片的尺寸或質量上都有不同的要求。原本為了滿足不同裝置的要求,在圖片儲存上會儲存各種所需尺寸的圖片,浪費了大量的磁碟空間,同時也浪費了高效能的硬體機器利用率。
同時公司對外的業務系統在數量和每個業務系統支撐的使用者群方面也在快速的增長,勢必會在對圖片的請求上出現爆炸式的增長,這對圖片系統的快速反映和高可用性提出了更高的要求,在保證公司的快速發展前提下,如何不降低使用者使用系統的體驗質量,如何保證7x24小時的高可靠性的服務,在這個契機下,我們推出了分散式圖片系統。
該系統在設計之初就充分考慮了上述問題,同時考慮到公司業務快速發展下,系統日後的可持續發展和系統的擴充套件性,從更全域性的高度來定位這個系統的價值和目標,經過設計和論證,該系統在以下方面提供的服務和支援:

  • 前端採用Nginx為web伺服器,利用其高併發特性,提供對高併發訪問量的支援
  • 利用nginx的代理快取特性和硬體的海量磁碟容量,為系統搭建了圖片快取模組,保證系統對已經處理過的圖片資源進行再次訪問時快速有效的提供響應,提高了系統的響應速度並避免了資源的重複執行,造成浪費,提高了系統利用率
  • 圖片資料來源採用了多套方案實現,為使公司原有業務、新開發業務能快速使用分散式圖片系統提供支援,減少了使用系統的複雜性
  • 其中一種資料資料來源採用了高效能的TFS分散式圖片儲存系統,利用多個資料節點,產生同一份資料的多份冗餘備份,提高了資料的安全性,為遇到故障時資料的快速恢復提供了支援
  • 能夠應對客戶端日益變化的希望獲取各種圖片尺寸的訴求,執行即時壓縮和圖片處理演算法,快速處理後返回。避免原有系統為應對新增某一種新的圖片尺寸,而必須將全部圖片重新生成一份該尺寸,造成儲存空間的浪費
  • 圖片處理模組能夠應對不同系統對圖片質量的不同需求,對要求高的可以採用較好的圖片處理演算法,對一般要求的可以採用一般的圖片處理演算法。
  • 整體系統採用模組化劃分,將系統分為各個部分,減少了系統的耦合性,增強了每個模組的獨立性,整個系統採用分散式部署結構,防止單點結構的出現,為防止系統出現雪崩提供支援

專案的目的


a). 圖片冗餘儲存,增強儲存安全
b). 減少縮圖數量,降低儲存容量(60%)
c). 滿足日益繁多的圖片尺寸格式需求

專案的意義


由圖片單純的檔案儲存變成一個系統平臺,規則解析對於系統擴充套件提供靈活機制。使移動終端的圖片格式需求不再受限。


系統使用到的技術


a) Nginx, Nginx proxy-store
b) C++
c) Opencv
d) ImageMagick、GraphicsMagick


系統圖
系統部署圖

分散式圖片系統



系統模組間呼叫圖

分散式圖片系統




模組介紹


在設計之初,就按照功能對系統進行了模組化劃分,目的是明確各個模組的功能邊界,在每個模組內部封裝實現細節,對外暴露出模組的訪問介面,方便了模組間的通訊和資料交換,同時各個模組的內部修改也不影響模組間的介面呼叫程式碼,最終為實現多資料來源多圖片處理演算法提供了良好的模型支援。


前端模組-Nginx


使用nginx自定義module,接收http請求,在自定義module的handler中呼叫分散式圖片實現。


代理快取模組


圖片伺服器使用 Nginx 的 proxy_store 把主伺服器的靜態內容快取到本地磁碟。 針對一張圖片的一次訪問結束後,其圖片處理結果被快取到處理機器的磁碟,以後針對該張圖片相同目標尺寸的圖片訪問將不再經過圖片壓縮圖片處理模組,直接從本地硬碟上讀取返回。 從而避免CPU重複壓縮圖片的情況。
由於Nginx的Proxy_store的磁碟需要提前分配磁碟空間,而磁碟空間又有一定的容量限制,所以對於一定時間後的快取圖片,我們執行刪除磁碟圖片操作,釋放快取空間,為新近處理後的圖片提供磁碟空間進行快取,做到一個動態的流動,使磁碟容量一直維持一個流動的平衡。
當處理後的圖片被磁碟快取後,當客戶端重新上傳了圖片源,我們會釋放原本快取的圖片處理結果,下次再請求這種圖片時,重新執行圖片壓縮,重新快取。保證資料的一致性。


排程控制模組(parser module)


該模組作為統一接收資料和返回處理結果的協調者角色,整個流程包括:
a) 接收來自外部的圖片請求
b) 對圖片請求進行處理
c) 處理結果執行規則匹配、驗證等操作,其中會呼叫壓縮防攻擊模組
d) 如果不符合處理要求,不再向下執行處理,立刻返回
e) 如果請求符合約定,則依次向下呼叫圖片儲存模組和圖片運算模組,並最終將處理結果返回給呼叫者。
另外,該模組負責處理各種業務邏輯錯誤,當請求的URL沒有匹配某個rule物件下的運算元據時;當獲取圖片源發生錯誤時;當呼叫圖片處理模組發生錯誤時;以及其他異常情況下時,必須向請求端返回預設圖片,以保證每一個請求的流程完整性,避免造成程式崩潰,導致應用無法正常再被使用。


壓縮防攻擊模組


由於圖片的大小是在呼叫時才動態生成,而圖片壓縮是一種很費伺服器CPU資源的操作,當呼叫者頻繁切換呼叫圖片並隨機調整圖片尺寸,這種情況下因為CDN上不存在此種格式的圖片快取而被直接穿透,直接消耗盡伺服器CPU資源,從而使圖片壓縮模組停止正常服務,進而達到攻擊該系統的目的。防攻擊模組在每收到一個圖片壓縮請求時,根據名稱空間及所屬專案,從圖片尺寸註冊中心獲取該專案提供的所有圖片尺寸列表,如果請求的圖片格式不在該列表內則拒絕提供圖片操作服務。


圖片存取模組(data module)


對外提供獲取原始圖片源的介面,模組針對介面程式設計,提供針對各種情況下的圖片儲存實現,現已實現的圖片源的模組包括:
a) Tfs檔案儲存系統
b) 本地圖片檔案儲存
圖片存取模組的設計,提供了中間尺寸的概念,客戶端對圖片的尺寸是任意的,如果圖片源中只儲存原始圖片,當請求的圖片尺寸與原始圖片源相差甚遠時,在執行圖片即時壓縮時,會造成由一張很大的原圖壓縮成很小的小圖,損失了圖片的大部分質量,而且佔用了較多的CPU資源,鑑於這種情況,在儲存原始圖片時,某種業務除了儲存原圖外,還會儲存預定義的中間尺寸圖片,在呼叫獲取圖片源介面前,根據目標圖尺寸查詢是否存在與之最接近的中間尺寸圖,如果存在,獲取中間尺寸圖作為圖片處理模組輸入源,否則,獲取原始圖片作為圖片處理輸入源。
該功能的正確使用,對於提高CPU處理效率,減少CPU額外運算都有一定的效果。


圖片運算模組(img-process module)


圖片即時壓縮核心模組程式碼,與圖片儲存模組類似,對外提供統一的圖片處理介面,模組內部針對介面實現多種圖片處理演算法,可以根據不同的業務需要,使用不同的圖片處理演算法,完成不用的業務需求要求。目前完成的圖片演算法包括:
a) Opencv壓縮演算法
b) GraphicsMagick壓縮演算法
c) ImageMagick壓縮演算法
其中每種圖片壓縮演算法都需要支援根據圖片質量引數進行不同質量的圖片壓縮,同時介面支援對圖片打水印操作,支援多張水印操作。
可動態支援其他的圖片處理演算法,只需要實現約定的圖片處理介面,完成特定演算法下的圖片縮放和圖片水印操作,即可快速的切換一種新的圖片處理演算法。

作者:李航


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559758/viewspace-2677161/,如需轉載,請註明出處,否則將追究法律責任。

相關文章