分享照片是Facebook上最流行的的功能之一。截至目前,用戶已經上傳超過15億張照片,這使得Facebook成為最大的照片共享網站。對於每一個上傳的照片,Facebook都生成並存儲四個大小不同的圖像,從而轉化為共60億張照片,總容量超過1.5PB。目前以每周220萬新照片的速度增長,相當於每周要額外增加25TB存儲。在高峰期每秒需要傳輸55萬照片。這些數字對Facebook的照片存儲基礎設施的一個重大的挑戰。
舊的 NFS 照片架構
老的照片系統架構分以下幾個層:
上傳層接收用戶上傳的照片並保存在 NFS 存儲層。
照片服務層接收 HTTP 請求並從 NFS 存儲層輸出照片。
NFS存儲層建立在商業存儲系統之上。
因為每張照片都以文件形式單獨存儲,這樣龐大的照片量導致非常龐大的元數據規模,超過了 NFS 存儲層的緩存上限,導致每次請求上傳都包含多次I/O操作。龐大的元數據成為整個照片架構的瓶頸。這就是為什麼 Facebook 主要依賴 CDN 的原因。為了解決這些問題,他們做了兩項優化:
因為每張照片都以文件形式單獨存儲,大量為目錄及文件在NFS 存儲層上產生了大量的元數據, 這個規模的元數據量遠遠超過了超過了NFS 存儲層的緩存上限,導致每次招聘請求會上傳都包含多次I/O操作。龐大的元數據成為整個照片架構的瓶頸。這就是為什麼 Facebook主要依賴 CDN 的原因。為了解決這些問題,他們做了兩項優化:
Cachr: 一個緩存服務器,緩存 Facebook 的小尺寸用戶資料照片。
NFS文件句柄緩存:部署在照片輸出層,以降低 NFS 存儲層的元數據開銷。
新的 Haystack 照片架構
新的照片架構將輸出層和存儲層合並為一個物理層,建立在一個基於HTTP 的照片服務器上,照片存儲在一個叫做haystack 的對象庫,以消除照片讀取操作中不必要的元數據開銷。新架構中,I/O 操作只針對真正的照片數據(而不是文件系統元數據)。haystack 可以細分為以下幾個功能層:
HTTP 服務器
照片存儲
Haystack 對象存儲
文件系統
存儲空間
在下面的介紹中,我們會對於上述的每個功能層做詳細的講述。
存儲空間
Haystack 部署在商業存儲刀片服務器上,典型配置為一個2U的服務器,包含:
兩個4核CPU
16GB – 32GB 內存
硬件 RAID,含256-512M NVRAM 高速緩存
超過12個1TB SATA 硬盤
每個刀片服務器提供大約10TB的存儲能力,使用了硬件 RAID-6, RAID 6在保持低成本的基礎上實現了很好的性能和冗余。不佳的寫性能可以通過RAID控制器和NVRAM緩存回寫解決,寫由於讀取大多是隨機的,NVRAM緩存是完全用於寫入的。
文件系統
Haystack 對象庫是建立在10TB容量的單一文件系統之上。
圖片讀取請求需要在讀取系統調用這些文件的位置偏移,但是為了執行讀取操作,文件系統必須先找到實際物理卷上的數據。文件系統中的每個文件都被一個叫做inode結構標識。inode包含了一個磁盤上邏輯文件偏移和物理區塊偏移的映射。在使用的特殊類型文件系統時大文件塊映射可能相當大。
基於文件系統的區塊為給個邏輯區塊和大文件保存映射。這些信息通常不適合保存在inode的緩存中,而是存儲在在間接地址塊。所以在讀取文件的時候必須按照特定的流程。這裡可以多個是間接地址塊,所以一個讀取會產生多個I/O取決於是否間接地址塊被緩存。
該系統只為連續范圍的區塊保持映射。一個連續的大文件的塊映射可以只由一個范圍的標識,這樣是適應inode的系統需求的。但是,如果該文件是一個被切割的不連續的塊的話,他的塊地圖可能非常的大。以上可以通過文件系統主動為大的物理文件分配大塊的空間來減少碎片。
目前使用的文件系統為XFS,一個很大程度提供高效的文件預分配系統。
Haystack 對象存儲
Haystack 是一個簡單的日志結構(只能追加),存儲著其內部數據對象的指針。一個 Haystack 包括兩個文件,包括指針和索引。下面的圖片將描述haystack存儲文件的布局:
haystack最前面的8K存儲是被超級塊占用。緊隨超級塊是針,每針組成的一個頭部,數據和尾部: