磁盤緩存--YYCache 設計思路

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

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

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

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

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

disk_cache_bench_result

 

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 或其餘淘汰算法
缺點:單條數據較大的時候讀寫性能較差。spa

做者:10m每秒滑行 連接:https://www.jianshu.com/p/10331a0941c4 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。
相關文章
相關標籤/搜索