查看redis缓存大小_一个 bug 引发了服务器崩溃,对应 redis 的 key 回收原理你清楚了吗?...
1 背景
項目中使用了 redis 做旁路緩存。讀請求到來時,有以下操作:1.檢查緩存,有則返回2.沒有則讀取數據庫,將結果回寫到緩存中。
寫請求到來時,有以下操作:1.更新數據庫 2.更新緩存(實際上刪緩存更合適,具體參見 高并發場景下,到底先更新緩存還是先更新數據庫)。
使用該方案 redis 正常運行,一段時間后,服務器宕機,提示 aborted core dumped 錯誤。
2 問題排查
問題定位
錯誤提示明顯的定位了錯誤位置,根據提示找到相關代碼
?await??client.setAsync(key,JSON.stringfy(value));原來是在 redis 寫入時引發的,那就先查看下內存占用情況。
檢查內存
輸出結果很長,就不一一展開了。這里面有幾個關鍵指標:
used_memory?:當前 redis 使用內存大小。這部分內存包含 redis 內部開銷和數據占用的內存。單位是字節(byte), 由 redis 分配器分配
used_memory_rss?:向操作系統申請的內存大小,即 redis 使用的物理內存大小。這個值和 top 、ps 命令得到的結果一致。
mem_fragmentation_ratio?:內存碎片率,ratio = used_memory_rss/used_memory。通常 used_memory_rss 會稍高于 used_memory。ratio 指數>1表明有內存碎片,越大表明越多,ratio 指數<1表明正在使用虛擬內存,虛擬內存其實就是硬盤,性能比內存低得多,這是應該增強機器的內存以提高性能。一般來說,ratio 的數值在1 ~ 1.5之間是比較健康的。
查看 key 回收策略
首先了解 redis 控制 key 回收策略的配置項:maxmemory-policy。它的作用是:當內存占用到達最大限制時,redis 會根據設定的回收策略移除 keys。命令行查看memory-policy:
??config?get?maxmemory-policy得到結果是 "noeviction",noeviction 是默認值,表示禁止淘汰數據。
當內存到達上限后,如果調用了 set、lpush 等需要占用內存的命令,noeviction 策略則會返回 error。
noeviction 策略一般使用情況如下:
- 使用 redis 作為 LRU 或者 LFU 緩存
- 對一個實例設置了嚴格的內存限制
3 解決方法
查看了內存占用情況和 key 回收策略,可以判斷,這是由于 redis 中 key 占用內存過大,并且沒進行回收,導致內存占滿崩潰。
因此解決方案從這兩個角度入手:
增大 redis 內存上限
maxmemory 默認是0,不限制最大內存。64位系統是不限制內存的,32位系統最多使用3GB內存。一般推薦 redis 內存設置為最大物理內存的一半
命令行設置:(當前實例無需重啟,立即生效)
?config?set?maxmemory?1024更改 redis.config (實例重啟后生效)
?maxmemory?1024設置 key 回收策略
redis 有以下回收策略:
- volatile-lru -> 使用 LRU 算法刪除(范圍:設置了生存時間的鍵)
- allkeys-lru -> 使用 LRU 算法刪除鍵(范圍:所有鍵)
- volatile-lfu -> 使用 LFU 算法刪除(范圍:設置了生存時間的鍵)
- allkeys-lfu -> 使用 LFU 算法刪除鍵(范圍:所有鍵)
- volatile-random -> 隨機刪除一個鍵(范圍:設置了生存時間的鍵)
- allkeys-random -> 隨機刪除一個鍵(范圍:所有鍵)
- volatile-ttl -> 刪除生存時間最近的一個鍵
- noeviction -> 不刪除,直接在寫操作時返回錯誤(默認)
一般使用 volatile-lru 和 allkeys-lru 算法居多,LRU 是最近最久未使用算法。但它不是精準的 LRU 算法。
實際上,redis 為了節省內存,使用了?合適的LRU 算法。具體實現是:采樣5個 key,通過 LRU 算法獲得最近最久未使用的 key 并回收。采樣大小可通過 maxmemory-samples 調整,默認是5.
注意:設置了 key 回收策略,不代表不會報錯。當沒有合適的 key 回收時,redis 同樣會返回錯誤。
4 寫在最后
服務器出現了崩潰,定位錯誤為 redis 的 set 操作。解決方案則是:增大 redis 內存上限或者設置 key 回收策略。
實際上,錯誤背后反應的是 redis 的內存管理機制。而除了 key 回收,redis 內存管理還有過期刪除機制。其內部實現使用的是惰性刪除和定期刪除。(不在本文討論范圍內,有時間會另寫一篇文章~)
隨著 redis 使用的深入,其背后的原理面紗也一層層揭開。Daemon 的心得是:結合實際遇到的問題,再針對性的查看原理性知識,成長會更快~
大家如果有什么疑問或者其他任何事情,歡迎添加 Daemon 的個人微信號交流~
總結
以上是生活随笔為你收集整理的查看redis缓存大小_一个 bug 引发了服务器崩溃,对应 redis 的 key 回收原理你清楚了吗?...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 5.6 主从同步配置_Mys
- 下一篇: pythonset操作教程_Python