![]()
作者 | Sergio De Simone
譯者 | 田橙
為了改進 Android 應用中的圖片緩存管理,Grab 的工程師將原有的 最近最少使用(Least Recently Used,LRU)緩存機制升級為時間感知最近最少使用(Time-Aware Least Recently Used,TLRU)緩存。這一改進使他們能夠更高效地回收存儲空間,同時不會降低用戶體驗,也不會增加服務器成本。
Grab 的 Android 應用使用 Glide 作為主要的圖片加載框架。該框架內置了一個 LRU 緩存,用于在本地存儲圖片,從而減少網絡請求、提升加載速度并降低服務器開銷。然而,數據分析顯示,使用 100 MB 的 LRU 緩存存在明顯問題:對于許多用戶來說,緩存空間很快就被填滿,導致性能下降;而在另一些情況下,如果緩存始終沒有達到大小上限,圖片可能會在緩存中保留數月之久,從而造成存儲空間浪費。
為了繞過這些限制,Grab 工程師決定在 LRU 的基礎上引入基于時間的過期機制。TLRU 通過三個參數進行控制:首先是 Time To Live(TTL),用于確定緩存條目在何時被視為過期;其次是最小緩存容量閾值,確保即使緩存條目已過期,只要緩存容量不足,關鍵圖片仍然可以繼續保留;最后是最大緩存容量,用于限制緩存的存儲上限。
在實現方案上,Grab 工程師并沒有從零開始編寫 TLRU,而是選擇 fork Glide 項目并擴展其 DiskLruCache 實現,以利用其“成熟且經過大量實踐驗證的基礎架構”。
這一實現方式在 Android 生態中被廣泛采用,并且已經處理了許多復雜的邊界情況,例如崩潰恢復、線程安全以及性能優化等。如果從零實現這些能力,需要投入大量額外的工程工作。
為了支持 TLRU,DiskLruCache 需要在三個方面進行擴展:一是增加對最近訪問時間(last-access time)的追蹤;二是實現基于時間的緩存淘汰邏輯;三是提供現有用戶緩存的遷移機制。
其中,記錄最近訪問時間是為了能夠按照“最近訪問順序”對緩存條目進行排序,并且這些時間信息必須在應用重啟后仍然能夠保留。時間驅動的淘汰邏輯會在每次緩存訪問時運行,用于檢查最近最少訪問的條目是否已經過期,如果過期則將其移除。
對于已有緩存的遷移,主要挑戰在于如何為原本的 LRU 緩存條目分配最近訪問時間戳。由于文件系統 API 無法提供可靠的時間來源,Grab 工程師最終決定為所有緩存條目統一賦予遷移時間戳。
這種方式可以保留所有現有緩存內容,并建立一個一致的時間基線。不過,它也意味著必須等待 一個完整的 TTL 周期之后,緩存淘汰機制的全部效果才會體現出來。同時,他們還確保了雙向兼容性:原始的 LRU 實現可以通過忽略時間戳后綴來讀取 TLRU 的日志文件,從而在需要時能夠安全回滾。
另一個挑戰是確定最佳配置參數,這需要通過受控實驗來完成。
Grab 為此設定了明確的成功標準:在從 LRU 遷移到 TLRU 的過程中,緩存命中率下降不得超過 3 個百分點(pp)。例如,如果命中率從 59% 降至 56%,就意味著服務器請求量將增加約 7%。這一閾值在存儲優化與性能影響之間取得了平衡。
通過這種方案,95% 的應用用戶緩存大小減少了約 50 MB,而緩存規模最大的 5% 用戶則獲得了更為顯著的節省。基于這些結果,Grab 工程師估算,在保持緩存命中率處于可接受范圍、且不增加服務器成本的前提下,他們可以在用戶設備上回收數 TB 級別的存儲空間。
原始文章對 LRU 的行為機制以及 TLRU 的實現細節提供了大量更為深入的技術說明,遠超本文所能覆蓋的范圍。如果希望了解完整實現細節,建議閱讀原文。
https://www.infoq.com/news/2026/03/grab-tlru-image-cache/
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.