1. 程式人生 > >磁盤緩存--YYCache 設計思路

磁盤緩存--YYCache 設計思路

讀取 ace 包括 鏈接 簡單 直接 快的 value 其他

為了設計一個比較好的磁盤緩存,我調查了大量的開源庫,包括 TMDiskCache、PINDiskCache、SDWebImage、FastImageCache 等,也調查了一些閉源的實現,包括 NSURLCache、Facebook 的 FBDiskCache 等。他們的實現技術大致分為三類:基於文件讀寫、基於 mmap 文件內存映射、基於數據庫。

TMDiskCache, PINDiskCache, SDWebImage 等緩存,都是基於文件系統的,即一個 Value 對應一個文件,通過文件讀寫來緩存數據。他們的實現都比較簡單,性能也都相近,缺點也是同樣的:不方便擴展、沒有元數據、難以實現較好的淘汰算法、數據統計緩慢。

FastImageCache 采用的是 mmap 將文件映射到內存。用過 MongoDB 的人應該很熟悉 mmap 的缺陷:熱數據的文件不要超過物理內存大小,不然 mmap 會導致內存交換嚴重降低性能;另外內存中的數據是定時 flush 到文件的,如果數據還未同步時程序掛掉,就會導致數據錯誤。拋開這些缺陷來說,mmap 性能非常高。

NSURLCache、FBDiskCache 都是基於 SQLite 數據庫的。基於數據庫的緩存可以很好的支持元數據、擴展方便、數據統計速度快,也很容易實現 LRU 或其他淘汰算法,唯一不確定的就是數據庫讀寫的性能,為此我評測了一下 SQLite 在真機上的表現。iPhone 6 64G 下,SQLite 寫入性能比直接寫文件要高,但讀取性能取決於數據大小:當單條數據小於 20K 時,數據越小 SQLite 讀取性能越高;單條數據大於 20K 時,直接寫為文件速度會更快一些。這和 SQLite 官網的描述基本一致。另外,直接從官網下載最新的 SQLite 源碼編譯,會比 iOS 系統自帶的 sqlite3.dylib 性能要高很多。基於 SQLite 的這種表現,磁盤緩存最好是把 SQLite 和文件存儲結合起來:key-value 元數據保存在 SQLite 中,而 value 數據則根據大小不同選擇 SQLite 或文件存儲。NSURLCache 選定的數據大小的閾值是 16K;FBDiskCache 則把所有 value 數據都保存成了文件。

我的 YYDiskCache 也是采用的 SQLite 配合文件的存儲方式,在 iPhone 6 64G 上的性能基準測試結果見下圖。在存取小數據 (NSNumber) 時,YYDiskCache 的性能遠遠高出基於文件存儲的庫;而較大數據的存取性能則比較接近了。但得益於 SQLite 存儲的元數據,YYDiskCache 實現了 LRU 淘汰算法、更快的數據統計,更多的容量控制選項。

技術分享圖片

https://blog.ibireme.com/2015/10/26/yycache/

iOS緩存設計(閱讀筆記)

市面上常見的緩存庫分類

基於文件系統 :TMDiskCache, PINDiskCache, SDWebImage

優點:實現都比較簡單
缺點:不方便擴展、沒有元數據、難以實現較好的淘汰算法、數據統計緩慢。

基於mmap :MMKV, FastImageCache,

優點:直接在內存中操作文件,對比文件 I/O 更快
缺點:熱數據的文件不要超過物理內存大小,不然 mmap 會導致內存交換嚴重降低性能,如果數據還未同步時程序掛掉,就會導致數據錯誤
(關於mmap詳解)

基於 SQLite : YapDataBase, FMDB,NSURLCache、FBDiskCache

優點: 支持元數據、擴展方便、數據統計速度快,也很容易實現 LRU 或其他淘汰算法
缺點:單條數據較大的時候讀寫性能較差。



作者:10m每秒滑行
鏈接:https://www.jianshu.com/p/10331a0941c4
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並註明出處。

磁盤緩存--YYCache 設計思路