概覽
Haystack 的基本思想就是將索引信息放在內存中,避免額外的IO。為了做到這一點,主要進行了兩方面的設計:
- 將小文件集合成大文件,減少文件數,從而減少了元信息的數目。
- 精簡文件元信息,去掉一切在 Facebook 場景中不需要的 POSIX 語義中元信息。
這樣就可以將數據元信息減小到一個內存可以放的下的量級,基本上每次每次數據訪問同一個一次 IO 就可以完成,而非以前的好幾次。
Facebook業務量級
2600w, 20P
峯值每秒鐘100w圖片。
key observation
傳統文件系統設計導致了過多的元信息查找,我們進行的減少了每個圖片的元信息使得Haystack 能夠在內存中進行所有的元信息查找操作。
定位
是一個對象存儲,用來存分享的圖片,針對的是一次寫,經常讀,從來不改,很少刪的數據集。不得不造輪子,因為傳統的分揀系統在如此高並發下,表現太差。
緣起
POSIX:目錄組織,並且每個文件存了過多的我們用不到的元信息,如用戶許可權。而在讀文件的時候,元信息必須預先讀入內存,在有數十億量級的文件時,這幾乎是不可忍受的。尤其對於NAS(network attached storage)
一個圖片讀寫需要三次訪問磁碟:
- 將文件名翻譯為inode
- 從磁碟讀入inode
- 根據inode信息讀文件本身
特點
高並發低延遲: CDN太貴,只能減少單個文件的metadata,然後將所有metadata保存在內存中,盡量做到一次訪盤。
容錯:異地備份
花銷: 比 CND 便宜。
簡單: 沒有那麼長時間的完善和測試,為了可用,只能做到盡量簡單。
舊流程
首先訪問 webserver,獲取圖片的的全局URL,裡麪包含圖片的位置信息。然後用CDN做緩存,命中返回,否則去 photo storage載入到CDN再訪問。
一個文件夾存數千張圖片的時候,目錄到block映射增大,一次不能載入內存,更加重了訪問次數。
總之,我們明白了無論是內部緩存還是外部緩存(memcached),都無助於長尾形式的訪問流量。
RAM-to-disk 比率,提高這個比率,但是一個圖片最少佔一個inode,從而帶來至少數百比特的額外元信息佔用。
新設計
傳統來說,如果網頁靜態內容服務如果出現瓶頸,就用CDN來解決。但是長尾文件的訪問還需靈眸他路,當然我們承認非熱門圖片的請求是可以訪盤的,但是我們可以減少這個次數。
一個圖片存一個文件元信息太多,那麼直觀的想法就是一堆圖片存成一個文件。
接下來我們區分兩種元信息:
- 應用元信息,用來構建瀏覽器可以用來檢索圖片的URL。
- 文件系統元信息,用以讓某個主機在其磁碟上定位該圖片。
概覽
三個主要組件:Haystack Store, Haystack Directory, Haystack Cache,簡略起見,我們將 Haystack 省略代稱為存儲,目錄和緩存。
- Store 對圖片的持久化層做了封裝,是唯一管理圖片文件元信息的組件。實現上來說,我們將主機的存儲進行劃分,稱為一個個物理上的 Volume。然後不同主機上的某幾個物理 volume 作為一組稱為一個邏輯上的 volume。那麼這幾個物理上的volume就是該邏輯 volume 的 replica,以進行備份,容錯和分流。
- Directory 維護了邏輯到物理的映射,以及另外一些應用信息,包括圖片到邏輯volume的映射,有空閑空間的邏輯volume
- Cache 起內部CDN的作用。當對熱門圖片的請求過來時,上層CDN不可用或者沒命中時,屏蔽了直接對store的訪問。
一個典型的要訪問CDN的圖片請求URL長這樣:http://?CDN?/?Cache?/?Machine id?/?Logical volume, Photo?
在CDN,Cache,Machine,層如果命中就返回,否則剝離該層次地址,然後將請求轉發到下一層。