網站首頁 編程語言 正文
什么是 Redis 大 key?
大 key 并不是指 key 的值很大,而是 key 對應的 value 很大。
一般而言,下面的情況被稱為大 key:
● 一個String類型的Key,它的值為5MB(數據過大);
● 一個List類型的Key,它的列表數量為20000個(列表數量過多);
● 一個ZSet類型的Key,它的成員數量為10000個(成員數量過多);
● 一個Hash格式的Key,它的成員數量雖然只有1000個但這些成員的value總大小為100MB(成員體積過大)
? 有時候會因為業務人員使用不當,在 Redis 實例中形成了很大的對象,比如一個很大的 hash 或一個很大的zset,都是可能出現的。這樣的對象給 Redis 的集群數據遷移帶來了很大的問題,因為在集群環境下,如果某個 key 太大,會導致數據遷移卡頓。另外在內存分配上,如果一個 key 太大,那么當它需要擴容時,會一次性申請更大的一塊內存,這也會導致卡頓。如果這個大 key 被刪除,內存會被一次性回收,卡頓現象也會再次產生。
? 在平時的業務開發中,要盡量避免大 key 的產生.
? 如果你觀察到 Redis 的內存大起大落,這極有可能是因為大 key 導致的,這時候你就需要定位出具體是哪個 key,進一步定位出具體的業務來源,然后再改進相關業務代碼設計。
為什么會出現大key?
- Redis數據結構使用不恰當:將Redis用在并不適合其能力的場景,造成Key的value過大,如使用String類型的Key存放大體積二進制文件型數據。
- 未及時清理垃圾數據:沒有對無效數據進行定期清理,造成如HASH類型Key中的成員持續不斷的增加。即一直往value塞數據,卻沒有刪除機制,value只會越來越大。
- 對業務預估不準確:業務上線前規劃設計考慮不足沒有對Key中的成員進行合理的拆分,造成個別Key中的成員數量過多。
- 明星、網紅的粉絲列表、某條熱點新聞的評論列表:假設我們使用List數據結構保存某個明星/網紅的粉絲,或者保存熱點新聞的評論列表,因為粉絲數量巨大,熱點新聞因為點擊率、評論數會很多,這樣List集合中存放的元素就會很多,可能導致value過大,進而產生大Key問題。
Redis中大key存在的問題
- 內存占用:大key占用大量的內存資源,導致Redis的內存壓力增加
- 網絡傳輸延遲:大key的讀寫操作可能會增加網絡的傳輸延遲,影響性能
- 持久化備份:大key的持久化備份需要更多的磁盤空間和時間
Redis中如何定位大key?
? 為了避免給線上Redis 帶來卡頓,就要用到 scan
指令,對于掃描出來的每一個key,使用type指令獲得 key的類型,然后使用相應數據結構的size
或者len
方法來得到它的大小,對于每一種類型,將大小排名的前若干名作為掃描結果展示出來。
? 上面這樣的過程需要編寫腳本,比較煩瑣,不過 Redis 官方已經在redis-cli 指令中提供了這樣的掃描功能,我們可以直接拿來使用。
redis-cli -h 127.0.0.1 -p6379 -a "password" -- bigkeys
如果你擔心這個指令會大幅拾升 Redis的ops導致線上報警,還可以增加一個休眠參數。
redis-cli -h 127.0.0.1 -p6379 -a "password" -- bigkeys -i 0.1
上面這個指令每隔100條 scan
指令就會休眠0.1s,ops 就不會劇烈拾升,但是掃描的時間會變長。
使用的時候注意事項:
- 最好選擇在從節點上執行該命令。因為主節點上執行時,會阻塞主節點;
- 如果沒有從節點,那么可以選擇在 Redis 實例業務壓力的低峰階段進行掃描查詢,以免影響到實例的正常運行;或者可以使用
-i
參數控制掃描間隔,避免長時間掃描降低 Redis 實例的性能。該方式的不足之處:
- 這個方法只能返回每種類型中最大的那個 bigkey,無法得到大小排在前 N 位的 bigkey;
- 對于集合類型來說,這個方法只統計集合元素個數的多少,而不是實際占用的內存量。但是,一個集合中的元素個數多,并不一定占用的內存就多。因為,有可能每個元素占用的內存很小,這樣的話,即使元素個數有很多,總內存開銷也不大;
如何刪除大 key?
刪除操作的本質是要釋放鍵值對占用的內存空間,不要小瞧內存的釋放過程。
釋放內存只是第一步,為了更加高效地管理內存空間,在應用程序釋放內存時,操作系統需要把釋放掉的內存塊插入一個空閑內存塊的鏈表,以便后續進行管理和再分配。這個過程本身需要一定時間,而且會阻塞當前釋放內存的應用程序。
所以,如果一下子釋放了大量內存,空閑內存塊鏈表操作時間就會增加,相應地就會造成 Redis 主線程的阻塞,如果主線程發生了阻塞,其他所有請求可能都會超時,超時越來越多,會造成 Redis 連接耗盡,產生各種異常。
因此,刪除大 key這一個動作,我們要小心。具體要怎么做呢?這里給出兩種方法:
- 分批次刪除
- 異步刪除(Redis 4.0版本以上)
如何解決Redis中大key存在的問題
- 把大key分成多個小key來存儲:比如把一個大的Hash結構分割成多個小的Hash結構,每個小的Hash結構代表一部分數據,這樣可以減小單個key的大小,去降低內存的壓力。
- 搭建Redis Cluster集群,把key分配到不同的hash slot槽所在的分片上:這樣可以降低單個Redis節點的存儲壓力
- 如果已經存在了大key,可以做數據的拆分和遷移:按照業務需求和規則把大key拆分成多個小key,并分布到不同的Redis實例上,在遷移完成之后,清除掉不需要使用的大key。
- 可以考慮使用壓縮算法進行壓縮,去減少存儲空間的占用:在存儲數據之前對數據進行壓縮,在讀取的時候進行解壓縮,以節省存儲空間和減少網絡傳輸的數據量。
- 從業務層面進行分析,了解大key產生的原因,并根據需求和訪問模式進行相應的優化:比如使用更合適的數據結構,優化業務邏輯的設計方法等等。
原文鏈接:https://blog.csdn.net/Mr_VK/article/details/132288349
- 上一篇:沒有了
- 下一篇:沒有了
相關推薦
- 2023-03-23 Android進階NestedScroll嵌套滑動機制實現吸頂效果詳解_Android
- 2022-09-05 Redis 數據刪除策略
- 2022-10-18 Qt?TCP實現簡單通信功能_C 語言
- 2022-06-01 C#文件操作、讀取文件、Debug/Trace類用法_C#教程
- 2022-10-14 ‘configurationClass‘ must be assignable to [org.hi
- 2022-04-28 shell命令返回值判斷的方法實現_linux shell
- 2022-08-05 Redis實現分布式鎖的五種方法詳解_Redis
- 2022-01-30 uni-app 打包H5空白頁面或者刷新404,加入偽靜態就可以解決
- 欄目分類
-
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支