ITBear旗下自媒體矩陣:

程序設(shè)計:Facebook是如何存儲數(shù)十億照片的?

   時間:2012-04-22 15:59:45 來源:新浪博客編輯:星輝 發(fā)表評論無障礙通道

分享照片是Facebook上最流行的的功能之一。截至目前,用戶已經(jīng)上傳超過15億張照片,這使得Facebook成為最大的照片共享網(wǎng)站。對于每一個上傳的照片,F(xiàn)acebook都生成并存儲四個大小不同的圖像,從而轉(zhuǎn)化為共60億張照片,總?cè)萘砍^1.5PB。目前以每周220萬新照片的速度增長,相當(dāng)于每周要額外增加25TB存儲。在高峰期每秒需要傳輸55萬照片。這些數(shù)字對Facebook的照片存儲基礎(chǔ)設(shè)施的一個重大的挑戰(zhàn)。

舊的 NFS 照片架構(gòu)

老的照片系統(tǒng)架構(gòu)分以下幾個層:

上傳層接收用戶上傳的照片并保存在 NFS 存儲層。

照片服務(wù)層接收 HTTP 請求并從 NFS 存儲層輸出照片。

NFS存儲層建立在商業(yè)存儲系統(tǒng)之上。

因為每張照片都以文件形式單獨存儲,這樣龐大的照片量導(dǎo)致非常龐大的元數(shù)據(jù)規(guī)模,超過了 NFS 存儲層的緩存上限,導(dǎo)致每次請求上傳都包含多次I/O操作。龐大的元數(shù)據(jù)成為整個照片架構(gòu)的瓶頸。這就是為什么 Facebook 主要依賴 CDN 的原因。為了解決這些問題,他們做了兩項優(yōu)化:

因為每張照片都以文件形式單獨存儲,大量為目錄及文件在NFS 存儲層上產(chǎn)生了大量的元數(shù)據(jù), 這個規(guī)模的元數(shù)據(jù)量遠(yuǎn)遠(yuǎn)超過了超過了NFS 存儲層的緩存上限,導(dǎo)致每次招聘請求會上傳都包含多次I/O操作。龐大的元數(shù)據(jù)成為整個照片架構(gòu)的瓶頸。這就是為什么 Facebook主要依賴 CDN 的原因。為了解決這些問題,他們做了兩項優(yōu)化: yixieshi

Cachr: 一個緩存服務(wù)器,緩存 Facebook 的小尺寸用戶資料照片。

NFS文件句柄緩存:部署在照片輸出層,以降低 NFS 存儲層的元數(shù)據(jù)開銷。

新的 Haystack 照片架構(gòu)

新的照片架構(gòu)將輸出層和存儲層合并為一個物理層,建立在一個基于HTTP 的照片服務(wù)器上,照片存儲在一個叫做haystack 的對象庫,以消除照片讀取操作中不必要的元數(shù)據(jù)開銷。新架構(gòu)中,I/O 操作只針對真正的照片數(shù)據(jù)(而不是文件系統(tǒng)元數(shù)據(jù))。haystack 可以細(xì)分為以下幾個功能層:

HTTP 服務(wù)器

照片存儲

Haystack 對象存儲

文件系統(tǒng)

存儲空間

在下面的介紹中,我們會對于上述的每個功能層做詳細(xì)的講述。

存儲空間

Haystack 部署在商業(yè)存儲刀片服務(wù)器上,典型配置為一個2U的服務(wù)器,包含:

兩個4核CPU

16GB – 32GB 內(nèi)存

硬件 RAID,含256-512M NVRAM 高速緩存

超過12個1TB SATA 硬盤

每個刀片服務(wù)器提供大約10TB的存儲能力,使用了硬件 RAID-6, RAID 6在保持低成本的基礎(chǔ)上實現(xiàn)了很好的性能和冗余。不佳的寫性能可以通過RAID控制器和NVRAM緩存回寫解決,寫由于讀取大多是隨機(jī)的,NVRAM緩存是完全用于寫入的。

文件系統(tǒng)

Haystack 對象庫是建立在10TB容量的單一文件系統(tǒng)之上。 yixieshi

圖片讀取請求需要在讀取系統(tǒng)調(diào)用這些文件的位置偏移,但是為了執(zhí)行讀取操作,文件系統(tǒng)必須先找到實際物理卷上的數(shù)據(jù)。文件系統(tǒng)中的每個文件都被一個叫做inode結(jié)構(gòu)標(biāo)識。inode包含了一個磁盤上邏輯文件偏移和物理區(qū)塊偏移的映射。在使用的特殊類型文件系統(tǒng)時大文件塊映射可能相當(dāng)大。 一些事

基于文件系統(tǒng)的區(qū)塊為給個邏輯區(qū)塊和大文件保存映射。這些信息通常不適合保存在inode的緩存中,而是存儲在在間接地址塊。所以在讀取文件的時候必須按照特定的流程。這里可以多個是間接地址塊,所以一個讀取會產(chǎn)生多個I/O取決于是否間接地址塊被緩存。

該系統(tǒng)只為連續(xù)范圍的區(qū)塊保持映射。一個連續(xù)的大文件的塊映射可以只由一個范圍的標(biāo)識,這樣是適應(yīng)inode的系統(tǒng)需求的。但是,如果該文件是一個被切割的不連續(xù)的塊的話,他的塊地圖可能非常的大。以上可以通過文件系統(tǒng)主動為大的物理文件分配大塊的空間來減少碎片。

目前使用的文件系統(tǒng)為XFS,一個很大程度提供高效的文件預(yù)分配系統(tǒng)。

Haystack 寫操作

Haystack 寫操作同步將指針追加到 haystack 存儲文件,當(dāng)指針積累到一定程度,就會生成索引寫到索引文件。由于索引文件是不是很關(guān)鍵,為了能有更快的性能所以采用異步的方式進(jìn)行寫入。

為了降低硬件故障帶來的損失,索引文件還會定期寫到存儲空間中。在崩潰或突然斷電的情況下,將haystack恢復(fù)處理器存儲中任何殘缺的針和截斷haystack存儲中最后一個有效的針。接下來,它會把丟失的針的索引記錄 寫到haystack文件的最后。

Haystack不允許重寫現(xiàn)有的針偏移,如果一個針數(shù)據(jù)需要被重寫,那么新版本必須使用相同的元組。應(yīng)用程序會自動分辨出這兩個相同的鍵,有最大偏移的便是最新的那一個。

Haystack 讀操作 一些事

傳到 haystack 讀操作的參數(shù)包括指針的偏移量,健,備用鍵,Cookie 以及數(shù)據(jù)大小。Haystack為數(shù)據(jù)大小添加頭部和尾部的長度,然后根據(jù)數(shù)據(jù)尺寸從文件中讀取整個指針。讀取操作成功的關(guān)鍵就是作為參數(shù)傳遞的健,備用鍵,Cookie是否匹配,數(shù)據(jù)是否通過了校驗,并且針沒有被刪除掉。(見下文)

Haystack 刪除操作

刪除操作比較簡單 – 只需要在 Haystack 存儲的指針字段中的“刪除”位標(biāo)記一下即可。并且,相關(guān)的索引記錄不會做任何的修改。是最終的應(yīng)用程序引用到的是一個刪除的針。像這樣一個讀取刪除針的操作將會返回一個相應(yīng)的錯誤給應(yīng)用程序??臻g對已刪除的針不做任何的回收,只有這樣,才能使 haystack 的空間非常的緊湊。(見下文) yixieshi

照片存儲服務(wù)器

照片存儲服務(wù)器負(fù)責(zé)接受 HTTP 請求,并轉(zhuǎn)換成相應(yīng)的 Haystack 操作。為了盡量減少服務(wù)器檢索照片時的I/O操作,該服務(wù)器維護(hù)著全部 Haystack 中文件索引的緩存。服務(wù)器啟動時,系統(tǒng)就會將這些索引讀到緩存中。由于每個節(jié)點都有數(shù)百萬張照片,必須保證索引的容量不會超過服務(wù)器的物理內(nèi)存。在內(nèi)存中僅需要保存查找照片所需的少量元數(shù)據(jù)即可。

對于用戶上傳的圖片,系統(tǒng)分配一個64位的獨立ID,照片接著被縮放成4種不同尺寸,每種尺寸的圖像擁有相同的隨機(jī) Cookie 和64位的密鑰,圖片尺寸描述(大,中,小,縮略圖)被存在代用key 中。接著上傳服務(wù)器通知照片存儲服務(wù)器將這些資料連同圖片存儲到 haystack 中。

照片存 儲的寫/修改操作 yixieshi

寫操作將照片數(shù)據(jù)寫到 Haystack 存儲并更新內(nèi)存中的索引。如果該索引記錄中包含了相同的鍵,那么這是一次對現(xiàn)有的照片進(jìn)行修改的操作。并且只要修改索引記錄中的偏移來反應(yīng)新圖像在haystack存儲文件的位置。照片存儲始終假定,如果有重復(fù)的圖像(圖像具有相同的鍵),有較大的偏移量的那個存儲是有效的。yixieshi

照片存儲的讀操作 一些事

傳遞給一個讀操作的參包括Haystack ID,照片的 Key, 尺寸以及 Cookie。服務(wù)器事先在緩存中按照照片的Key和所需文件的偏移進(jìn)行查找。如果找到了它,并向haystack發(fā)出讀取詞圖像的請求。按照上面說的,haystack的刪除操作并不更新它的索引記錄,因此添加到內(nèi)存中的索引可以包含以前刪除的照片的內(nèi)容。當(dāng)閱讀以前的刪除的照片失敗后,系統(tǒng)將在內(nèi)存的索引中色繪制詞圖片的偏移量為0.

照片存儲的刪除操作

通知 Haystack 執(zhí)行刪除操作之后,內(nèi)存中的索引緩存會被更新,將偏移量設(shè)置為0,表示照片已被刪除。

重新整理(壓縮)

重新整理(壓縮)是一種回收刪除和重復(fù)的針(針使用相同的Key)的在線操作。它會通過復(fù)制針跳過任何重復(fù)或刪除的條目創(chuàng)建一個新的 haystack。一旦此操作完成它就回去替換掉內(nèi)存中的文件和結(jié)構(gòu)。

HTTP 服務(wù)器

Http 框架使用的是簡單的基于開源的libevent庫的 evhttp 服務(wù)器。使用多線程,每個線程都可以單獨處理一個 HTTP 請求。因為我們的系統(tǒng)消耗大多是I/O操作,HTTP服務(wù)器的性能并不很重要。

結(jié)束語

Haystack 是一個基于 HTTP 的對象存儲,包含指向?qū)嶓w數(shù)據(jù)的指針,該架構(gòu)消除了文件系統(tǒng)元數(shù)據(jù)的開銷,并實現(xiàn)將全部索引直接存儲到緩存,以最小的 I/O 操作實現(xiàn)對照片的存儲和讀取。

本文作者為Facebook的工程師Peter Vajgel, Doug Beaver 和 Jason Sobel, 由標(biāo)點符進(jìn)行翻譯。

舉報 0 收藏 0 打賞 0評論 0
 
 
更多>同類資訊
全站最新
熱門內(nèi)容
網(wǎng)站首頁  |  關(guān)于我們  |  聯(lián)系方式  |  版權(quán)聲明  |  網(wǎng)站留言  |  RSS訂閱  |  違規(guī)舉報  |  開放轉(zhuǎn)載  |  滾動資訊  |  English Version