cdn的緩存數據是如何實現分片的,如何有效的實現各分片的存儲及刪除?
標題的分片概念有點模糊了,指的其實是類似nginx的ngx_http_slice_module模塊以及ats的cache_range_requests的切片功能,但是目前這兩種模塊其實都是有問題的,nginx的slice模塊在刪除緩存文件時尤為明顯,無法高效的進行刪除,ats的slice模塊只能說聊勝於無,並不能減少存儲及回源
瀉藥,首先如何實現分片:CDN的cache伺服器一般都自己實現了一個文件系統,以一定大小分片為基本存儲單位,而而當下游(也就是請求資源的用戶)發起請求時,cache服務在向上游(就是提供資源的源站)拉取資源時,以一定的固定大小分片保存在自己文件系統的各個單位中,並有自己的索引方式可以找到各內容的各個分片和總體信息。
題主第二個問題,關於效率,一般會採用LRU或LFU的演算法把經常命中的內容存在內存內,以增加訪問速度。此外linux系統自身vfs的緩存機制也有利於常用內容在內存中命中。
同時因為分片存儲必定伴隨著分片淘汰,刪除的高效方式是在刪除的時候只刪除對分片的索引,不刪內容,且索引一般保存於內存,內容則在下次寫入時直接覆蓋。此外在隨機淘汰之後,普通的文件系統會變得零散,而對於硬碟中零散的塊,讀寫效率降低,怎樣做到高效。目前比較先進的方案是採用隨機讀,順序寫的方式,也就是所謂COSS環形對象存儲系統,這裡不展開了具體實現參見ATS和squid的源碼。PS話說沒注意題主都加了squid 的標籤,squid開源,你既然想知道細節就去讀源碼或者懶一點讀分析的文章啊
沒有看過 ngx_http_slice_module 但是設計實現過視頻CDN的分片. 所以厚臉皮還是回答一下.
分片從應用角度來說, 可以分為幾個層面: 存儲, 分發, 服務
對於大文件來說, 分片肯定是非常有用的:
- 大文件的分片分發能夠大大提高分發效率和緩存速度.
- 分片存儲 可以將一個內容存在多個磁碟甚至多台機器上, 這可以提高存儲設備的負載均衡, 容錯, 性能可擴展性等很多方面的能力.
- 分片服務肯定是必需的, 你可以理解為類似HTTP Range的東西, 當然根據應用協議會有所不同, 假如一個視頻不能拖動那怎麼可以忍受? (其實最開始的土豆優酷就是除非已經客戶端緩存否則無法拖動的)
注意分片存儲的話, 和分片分發和服務本身並沒有什麼必要的關係. 比如BT協議, 假如在本地就是一整個文件, 但是不妨礙你做邏輯的分片來P2P分發(只要應用裡面做個邏輯分片索引即可). 比如RAID5可以認為是一個基於磁碟的分片, 但是在服務/分發上, 都可以視為整個文件來操作. 另一個方面, 即使存儲分發服務都是分片的, 但是他們的分片之間可能沒有什麼聯繫, 分發和服務經常是以Bytes或者KB為單位, 但是存儲分片為了效率和性能考慮, 常常是MB以上的單位.
對於分片存儲, 其實提問者可以先了解FAT32和Ext2/3 , COSS之類的文件系統, 再根據 CDN緩存的設計難點去理解一些分片方式的設計要點. 主要還是緩存單位的大數量,碎片化和管理, 以及因為上面幾個帶來的性能方面的折中. 很多時候是要根據特定的應用和緩存場景來設計的, 比如做視頻的, 很多視頻用戶就看個開頭, 所以刪除的時候, 一些不是很冷的片子可以保留開頭的分片. 刪除效率方面, 很多場景下面只要刪除分片內容的索引即可, 實際分配的空間可以以後在合適條件下回收(大部分文件系統都是這麼設計的).
不同場景的方案也有不同的考量, 還是得多了解一些實現, 看文檔和代碼, 然後考慮怎麼規避他們的缺點. 比如一些文件系統, 將緩存單位ID hash化以後, 再來存儲, 因為hash無法逆向, 所以這樣的實現假如沒有一些輔助措施, 很難實現比如刪除某個目錄下所有文件的操作或者刪除URL匹配某個正則表達式的操作的.
緩存跟存儲其實是分開的,緩存可以分片,存儲並不要求分片,只需要支持範圍讀取即可。至於緩存更新,可以參考動態內容緩存方式。比如etag。
存儲我覺得沒必要分片,緩存分片就可以了。
比較好奇在源站不支持 Range 的情況下,我們有沒有什麼方案可以在 CDN 上打開該功能
推薦閱讀:
※`a = false` 和 `if (a) { a = false; }` 哪個快?
※對於平均大小在 10M 至 50M 左右的文件下載服務來說,有沒有什麼成熟的緩存方案呢?
※為什麼從Intel Core i系列開始加入L3緩存,而不是使用更大的L2緩存?
※新浪微博、Twitter 等 SNS 社交網站如何合理規劃自己的緩存設計?
※Android 系統里的 RSS 訂閱會產生大量緩存垃圾么?如何清理?