日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

【Redis】Redis中大key怎么處理?

作者:Mr.VK 更新時間: 2024-03-10 編程語言

什么是 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?

  1. Redis數據結構使用不恰當:將Redis用在并不適合其能力的場景,造成Key的value過大,如使用String類型的Key存放大體積二進制文件型數據。
  2. 未及時清理垃圾數據:沒有對無效數據進行定期清理,造成如HASH類型Key中的成員持續不斷的增加。即一直往value塞數據,卻沒有刪除機制,value只會越來越大。
  3. 對業務預估不準確:業務上線前規劃設計考慮不足沒有對Key中的成員進行合理的拆分,造成個別Key中的成員數量過多。
  4. 明星、網紅的粉絲列表、某條熱點新聞的評論列表:假設我們使用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存在的問題

  1. 把大key分成多個小key來存儲:比如把一個大的Hash結構分割成多個小的Hash結構,每個小的Hash結構代表一部分數據,這樣可以減小單個key的大小,去降低內存的壓力。
  2. 搭建Redis Cluster集群,把key分配到不同的hash slot槽所在的分片上:這樣可以降低單個Redis節點的存儲壓力
  3. 如果已經存在了大key,可以做數據的拆分和遷移:按照業務需求和規則把大key拆分成多個小key,并分布到不同的Redis實例上,在遷移完成之后,清除掉不需要使用的大key。
  4. 可以考慮使用壓縮算法進行壓縮,去減少存儲空間的占用:在存儲數據之前對數據進行壓縮,在讀取的時候進行解壓縮,以節省存儲空間和減少網絡傳輸的數據量。
  5. 從業務層面進行分析,了解大key產生的原因,并根據需求和訪問模式進行相應的優化:比如使用更合適的數據結構,優化業務邏輯的設計方法等等。

原文鏈接:https://blog.csdn.net/Mr_VK/article/details/132288349

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新