java 最少使用(lru)置换算法_一篇文章学会如何基于LRU-K算法设计本地缓存实现流量削峰...
專注于Java領域優質技術號,歡迎關注
作者:一個Java菜鳥
1、背景介紹
1.1、現象
QPS突然增長2倍以上(45w~60w每分鐘) 將產生下面一些問題:
1)響應接口響應時長增加了5倍(qps增加了2倍);
2)機房局域網交換機帶寬報警(1kM帶寬使用了900多M);
3)從redis獲取數據接口響應時長增加等。
1.2、原因
1)某業務線對有限的產品進行推廣;
2)在短時間內有大量重復數據查詢請求;
3)短時間從redis獲取大量數據。
1.3、解決方案
大量請求獲取同一份數據,在本地存儲這些數據。
其優點如下:
1)直接從內存取數據,降低響應時間;
2)不走redis,減少服務與redis之間的交互流量;
3)最終實現流量削峰
2、LRU-K模型設計
2.1、LRU算法介紹
Least recently used(LRU,最近最少使用):根據數據的歷史訪問記錄淘汰數據。
核心思想
如果數據最近被訪問過,那么將來被訪問的幾率更高。
命中率
當存在熱點數據時,LRU的效率很好,但偶發性的、周期性的批量操作會導致LRU命中率急劇下降,緩存污染情況比較嚴重。
LRU算法模型如下圖:
1)新數據插入到鏈表頭部;
2)每當緩存命中(即緩存數據被訪問),則將數據移到鏈表頭部;
3)當鏈表滿的時候,將鏈表尾部的數據丟棄。
2.2、LRU-K算法設計
LRU-K中的K代表最近使用的次數。
主要目的
解決LRU算法“緩存污染”的問題。
核心思想
“最近使用過1次”的判斷標準擴展為“最近使用過K次”。
命中率
LRU-K降低了“緩存污染”帶來的問題,命中率比LRU要高。
LRU-K模型如下圖:
1)數據第一次被訪問,加入到訪問歷史記錄表(簡稱記錄表);在記錄表中對應的K單元中設置最后訪問時間=new(),且設置訪問次數為1;
2)如果數據訪問次數沒有達到K次,則訪問次數+1。最后訪問時間與當前時間間隔超過預設的值(如30秒),訪問次數清0并加1;
3)當數據訪問計數超過(>=)K次后,則訪問次數+1。將數據保存到LRU緩存隊列中,緩存隊列重新按照時間排序;
4)LRU緩存隊列中數據被再次訪問后,重新排序;
5)LRU緩存隊列需要淘汰數據時,淘汰緩存隊列中排在末尾的數據,即:淘汰“倒數第K次訪問離現在最久”的數據。
子模塊LRU存儲模型:
類似ConcurrentHashMap,大致由二維數組+鏈表+訪問隊列三部分組成
Segment數組每個節點包含訪問隊列,訪問隊列模型如下圖:
Segment數組每個節點都包含一個訪問隊列,通過這個隊列來實現lru算法;
訪問隊列是一個環狀雙向鏈表,LRU算法由訪問隊列實現
3、緩存框架
3.1、系統數據存儲組成
數據存儲使用DB+本地緩存(LocalCache)+Redis三層結構,如下圖:
3.2、數據查詢流程
先從本地緩存取,本地緩存沒有從redis取(同時更新本地緩存),redis沒有從DB取(同時更新Redis)。具體步驟如下圖:
1)先計算該數據獲取總次數
2)未達到K訪問記錄時直接從redis取數據
3)達到K次訪問記錄時,從本地緩存取,本地緩存不存在時從redis獲取數據(同時放入本地緩存中)
3.3、數據更新流程
刪除緩存數據后,會再次從redis獲取并更新緩存
4、調優過程
4.1、參數動態配置
配置參數如果放在Java類或配置文件中,每次調整都需要重啟服務,執行不方便。
配置參數包括 K次訪問統計數據清0時長(5分鐘->30秒)、K次訪問閥值參數、調優日志開關(調優時打開,平時關閉)、本地緩存最大數量等等。
動態調整+實時生效:配置參數放在可實時更新的組件中(如apollo),每次修改后會立即生效。
4.2、性能調優
4.2.1、多機器本地緩存同步增加原來的業務響應時長
優化方案:同步緩存操作改成異步
4.2.2、服務發布時接口抖動
優化方案:
1)服務啟動時執行比較耗時初始化操作:如jdbc初始化,K次統計結構初始化。
2)模擬核心dubbo接口,提前生成本地機器碼。
5、實際效果
5.1、效果(1)
1)優化參數前QPS增長時,響應時間未見明顯變短。如左右第1列
2)參數調優上線后。QPS明顯增加后,redis請求響應時間增加的情況下,整體響應時間未見變化。見左右最后1列
5.2、效果(2)
QPS增加4倍,響應時間未見變化,跟平時一樣
demo源代碼見:
https://download.csdn.net/download/love254443233/10672814參考方法:
com.example.liuyaohua.cache.lruk.LrukCacheTest總結
以上是生活随笔為你收集整理的java 最少使用(lru)置换算法_一篇文章学会如何基于LRU-K算法设计本地缓存实现流量削峰...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 连接redis_Redis 开
- 下一篇: hive 行转列和列转行的方法_Hive