目錄
Redis記憶體滿了怎麼辦?怎麼優化記憶體?
MySQL裡有2000w數據,redis中只存20w的數據,如何保證redis中的數據都是熱點數據
Redis主要消耗什麼實體資源?
Redis的記憶體用完了會發生什麼事?
談談快取資料的淘汰機制
談談LRU演算法
如何處理被淘汰的資料?
Redis怎麼優化記憶體?
首頁 資料庫 Redis 詳細解析Redis記憶體滿了怎麼去優化

詳細解析Redis記憶體滿了怎麼去優化

Mar 14, 2022 pm 05:09 PM
redis

這篇文章為大家帶來了關於Redis的相關知識,其中主要介紹了redis的記憶體滿了應該怎麼優化的相關問題,還包括了淘汰機制、LRU演算法以及處理淘汰的數據,希望對大家有幫助。

詳細解析Redis記憶體滿了怎麼去優化

推薦學習:Redis學習教學

Redis記憶體滿了怎麼辦?怎麼優化記憶體?

MySQL裡有2000w數據,redis中只存20w的數據,如何保證redis中的數據都是熱點數據

redis內存數據集大小上升到一定大小的時候,就會施行資料淘汰策略。

Redis主要消耗什麼實體資源?

記憶體。

Redis的記憶體用完了會發生什麼事?

如果達到設定的上限,Redis的寫指令會回傳錯誤訊息(但是讀取指令還可以正常回傳。)或者你可以設定記憶體淘汰機制,當Redis達到記憶體上限時會沖刷掉舊的內容。

談談快取資料的淘汰機制

Redis 快取有哪些淘汰策略?

  • 不進行資料淘汰的策略,只有 noeviction 這一種。

會進行淘汰的7 種策略,我們可以再進一步根據淘汰候選資料集的範圍把它們分成兩類:

  • 在設定了過期時間的數據中進行淘汰,包括volatile-random、volatile-ttl、volatile-lru、volatile-lfu四種。
  • 在所有資料範圍內進行淘汰,包括 allkeys-lru、allkeys-random、allkeys-lfu三種。
##volatile-lfu使用LFU 演算法選擇設定了過期時間的鍵值對
策略 規則
volatile-ttl 在篩選時,會針對設定了過期時間的鍵值對,根據過期時間的先後進行刪除,越早過期的越先被刪除。
volatile-random 在設定了過期時間的鍵值對中,進行隨機刪除。
volatile-lru 使用LRU 演算法篩選設定了過期時間的鍵值對
策略
#######allkeys-random######從所有鍵值對中隨機選擇並刪除資料;############allkeys -lru######使用LRU 演算法在所有資料中進行篩選############vallkeys-lfu######使用LFU 演算法在所有資料中進行篩選### ##########

談談LRU演算法

是按照最近最少使用的原則來篩選數據,最不常用的數據會被篩選出來,而最近頻繁使用的數據會留在快取中。

那具體是怎麼篩選的呢? LRU 會把所有的資料組織成一個鍊錶,鍊錶的頭和尾分別表示 MRU 端和 LRU 端,分別代表最近最常使用的資料和最近最不常用的資料。
詳細解析Redis記憶體滿了怎麼去優化
LRU 演算法背後的想法非常樸素:它認為剛剛被訪問的數據,肯定還會再次訪問,所以就把它放在MRU 端;長久不訪問的數據,肯定就不會再被存取了,所以就讓它逐漸後移到LRU 端,在快取滿時,就優先刪除它。

問題:LRU 演算法在實際實作時,需要用鍊錶管理所有的快取數據,這會帶來額外的空間開銷。而且,當有資料被存取時,需要在鍊錶上把該資料移動到 MRU 端,如果有大量資料被訪問,就會帶來很多鍊錶移動操作,會很耗時,進而降低 Redis 快取效能。

解決
在 Redis 中,LRU 演算法被做了簡化,以減輕資料淘汰對快取效能的影響。具體來說,Redis 預設會記錄每個資料的最近一次存取的時間戳記(由鍵值對資料結構 RedisObject 中的 lru 欄位記錄)。然後,Redis 在決定淘汰的數據時,第一次會隨機選出 N 個數據,把它們當作一個候選集合。接下來,Redis 會比較這 N 個資料的 lru 字段,把 lru 字段值最小的資料從快取中淘汰出去。
當需要再次淘汰資料時,Redis 需要挑選資料進入第一次淘汰時所建立的候選集合。這兒的挑選標準是:能進入候選集合的資料的 lru 欄位值必須小於候選集合中最小的 lru 值。當有新資料進入候選資料集後,如果候選資料集中的資料個數達到了 maxmemory-samples,Redis 就把候選資料集中 lru 欄位值最小的資料淘汰出去。

使用建議

  • 優先使用 allkeys-lru 策略。這樣,可以充分利用 LRU 這項經典快取演算法的優勢,把最近最常存取的資料留在快取中,提升應用程式的存取效能。如果你的業務資料中有明顯的冷熱資料區分,我建議你使用 allkeys-lru 策略。
  • 如果業務應用中的資料存取頻率相差不大,沒有明顯的冷熱資料區分,建議使用 allkeys-random 策略,隨機選擇淘汰的資料就行。
  • 如果你的業務中有置頂的需求,例如置頂新聞、置頂視頻,那麼,可以使用 volatile-lru 策略,同時不給這些置頂數據設定過期時間。這樣一來,這些需要置頂的資料一直不會被刪除,而其他資料會在過期時根據 LRU 規則進行篩選。

如何處理被淘汰的資料?

一旦被淘汰的數據選定後,如果這個數據是乾淨數據,那麼我們就直接刪除;如果這個數據是髒數據,我們需要把它寫回數據庫。

那要怎麼判斷一個資料到底是乾淨的還是髒的呢?

  • 乾淨資料和髒資料的差別在於,和最初從後端資料庫讀取時的值相比,有沒有被修改過。乾淨資料一直沒有被修改,所以後端資料庫裡的資料也是最新值。在替換時,它可以直接刪除。
  • 而髒資料就是曾經被修改過的,已經和後端資料庫中保存的資料不一致了。此時,如果不把髒資料寫回資料庫中,這個資料的最新值就遺失了,就會影響應用程式的正常使用。

即使淘汰的資料是髒數據,Redis 也不會把它們寫回資料庫。所以,我們在使用 Redis 快取時,如果資料被修改了,需要在資料修改時就將它寫回資料庫。否則,這個髒資料被淘汰時,會被 Redis 刪除,而資料庫裡也沒有最新的資料了。

Redis怎麼優化記憶體?

1、控制key的數量:當使用Redis儲存大量資料時,通常會存在大量鍵,過多的鍵同樣會消耗大量記憶體。 Redis本質是一個資料結構伺服器,它為我們提供多種資料結構,如hash,list,set,zset 等結構。使用Redis時不要進入一個誤區,大量使用get/set這樣的API,把Redis當成Memcached使用。對於儲存相同的資料內容利用Redis的資料結構降低外層鍵的數量,也可以節省大量記憶體。
2、縮減鍵值對象,降低Redis記憶體使用最直接的方式就是縮減鍵(key)和值(value)的長度。

  • key長度:如在設計鍵時,在完整描述業務情況下,鍵值越短越好。
  • value長度:值物件縮減比較複雜,常見需求是把業務物件序列化成二進位陣列放入Redis。首先應該在業務上精簡業務對象,去掉不必要的屬性避免儲存無效資料。其次在序列化工具選擇上,應該選擇更有效率的序列化工具來降低位元組數組大小。

3、編碼最佳化。 Redis對外提供了string,list,hash,set,zet等類型,但是Redis內部針對不同類型存在編碼的概念,所謂編碼就是具體使用哪種底層資料結構來實現。編碼不同將直接影響資料的記憶體佔用和讀寫效率。


  • 1、redisObject物件
    詳細解析Redis記憶體滿了怎麼去優化

#type欄位
利用集合類型數據,因為通常情況下很多小的Key-Value可以用更緊湊的方式存放在一起。盡可能使用散列表(hashes),散列表(是說散列表裡面儲存的數少)使用的記憶體非常小,所以你應該盡可能的將你的資料模型抽象化到一個散列表裡面。例如你的web系統中有一個用戶對象,不要為這個用戶的名稱,姓氏,郵箱,密碼設定單獨的key,而是應該把這個用戶的所有資訊儲存到一張散列表裡面。

encoding欄位:
採用不同的編碼實作記憶體佔用有明顯差異

lru欄位:
開發提示:可以使用scan object idletime 命令批量查詢哪些鍵長時間未被訪問,找出長時間不訪問的鍵進行清理降低內存佔用。

refcount欄位:
當物件為整數且範圍在[0-9999]時,Redis可以使用共享物件的方式來節省記憶體。

ptr欄位 :
開發提示:高並發寫入場景中,在條件允許的情況下建議字串長度控制在39位元組以內,減少創建redisObject記憶體分配次數從而提高效能。


  • 2、縮減鍵值物件
    降低Redis記憶體使用最直接的方式就是縮減鍵(key)和值(value)的長度。
    可以使用通用壓縮演算法壓縮json,xml後再存入Redis,從而降低記憶體佔用

  • 3、共享物件池
    物件共享池指Redis內部維護[0-9999]的整數物件池。創建大量的整數類型redisObject存在記憶體開銷,每個redisObject內部結構至少佔16字節,甚至超過了整數自身空間消耗。所以Redis記憶體維護一個[0-9999]的整數物件池,用於節約記憶體。除了整數值對象,其他型別如list,hash,set,zset內部元素也可以使用整數物件池。 因此開發中在滿足需求的前提下,盡量使用整數物件以節省記憶體。
    當設定maxmemory並啟用LRU相關淘汰策略如:volatile-lru,allkeys-lru時,Redis禁止使用共享物件池。

為什麼開啟maxmemory和LRU淘汰策略後物件池無效?
LRU演算法需要取得物件最後被存取時間,以便淘汰最長未存取數據,每個物件最後存取時間儲存在redisObject物件的lru欄位。物件共享意味著多個引用共享同一個redisObject,這時lru欄位也會被共享,導致無法取得每個物件的最後存取時間。如果沒有設定maxmemory,直到記憶體被用盡Redis也不會觸發記憶體回收,所以共享物件池可以正常運作。
綜上所述,共享物件池與maxmemory LRU策略衝突,使用時需要注意。

為什麼只有整數物件池?
首先整數物件池復用的幾率最大,其次物件共享的一個關鍵操作就是判斷相等性,Redis之所以只有整數物件池,是因為整數比較演算法時間複雜度為O(1),只保留一萬個整數為了防止物件池浪費。如果是字串判斷相等性,時間複雜度變成O(n),特別是長字串更消耗效能(浮點數在Redis內部使用字串儲存)。對於較複雜的資料結構如hash,list等,相等性判斷需要O(n2)。對於單執行緒的Redis來說,這樣的開銷顯然不合理,因此Redis只保留整數共享物件池。


  • 4、字串最佳化
    Redis沒有採用原生C語言的字串型別而是自己實作了字串結構,內部簡單動態字串,簡稱SDS。

字串結構

  • 特點:
    O(1)時間複雜度取得:字串長度,已用長度,未用長度。
    可用於保存位元組數組,支援安全的二進位資料儲存。
    內部實作空間預先分配機制,降低記憶體再分配次數。
    惰性刪除機制,字串縮減後的空間不釋放,作為預先分配空間保留。

預先分配機制

  • 開發提示:盡量減少字串頻繁修改操作如append,setrange, 改為直接使用set修改字串,降低預分配帶來的記憶體浪費和記憶體碎片化。

字串重構:基於hash類型的次要編碼方式。

  • 二級編碼怎麼用?
    二級編碼方法中所採用的 ID 長度是有講究的。
    涉及一個問題–Hash 類型底層結構小於設定值時使用壓縮列表,大於設定值時使用哈希表。
    一旦從壓縮列表轉為了哈希表,Hash 類型會一直用哈希表進行保存,而不會再轉回壓縮列表。
    在節省記憶體空間方面,哈希表就沒有壓縮列表那麼有效率。為能充分使用壓縮清單的精簡記憶體佈局,一般要控制保存在 Hash 中的元素個數。

  • 5.編碼優化
    使用壓縮列表ziplist編碼的hash類型依然比使用hashtable編碼的集合節省大量記憶體。

  • 6.控制key的數量
    開發提示:使用ziplist hash優化keys後,如果想使用逾時刪除功能,開發人員可以儲存每個物件寫入的時間,再透過定時任務使用hscan指令掃描數據,找出hash內逾時的資料項刪除即可。

當Redis記憶體不足時,首先考慮的問題不是加機器做水平擴展,應該先嘗試做記憶體優化。當遇到瓶頸時,再去考慮水平擴展。即使對於叢集化方案,垂直層面最佳化也同樣重要,避免不必要的資源浪費和叢集化後的管理成本。

推薦學習:Redis教學

#

以上是詳細解析Redis記憶體滿了怎麼去優化的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1318
25
PHP教程
1269
29
C# 教程
1248
24
redis集群模式怎麼搭建 redis集群模式怎麼搭建 Apr 10, 2025 pm 10:15 PM

Redis集群模式通過分片將Redis實例部署到多個服務器,提高可擴展性和可用性。搭建步驟如下:創建奇數個Redis實例,端口不同;創建3個sentinel實例,監控Redis實例並進行故障轉移;配置sentinel配置文件,添加監控Redis實例信息和故障轉移設置;配置Redis實例配置文件,啟用集群模式並指定集群信息文件路徑;創建nodes.conf文件,包含各Redis實例的信息;啟動集群,執行create命令創建集群並指定副本數量;登錄集群執行CLUSTER INFO命令驗證集群狀態;使

redis數據怎麼清空 redis數據怎麼清空 Apr 10, 2025 pm 10:06 PM

如何清空 Redis 數據:使用 FLUSHALL 命令清除所有鍵值。使用 FLUSHDB 命令清除當前選定數據庫的鍵值。使用 SELECT 切換數據庫,再使用 FLUSHDB 清除多個數據庫。使用 DEL 命令刪除特定鍵。使用 redis-cli 工具清空數據。

redis怎麼讀取隊列 redis怎麼讀取隊列 Apr 10, 2025 pm 10:12 PM

要從 Redis 讀取隊列,需要獲取隊列名稱、使用 LPOP 命令讀取元素,並處理空隊列。具體步驟如下:獲取隊列名稱:以 "queue:" 前綴命名,如 "queue:my-queue"。使用 LPOP 命令:從隊列頭部彈出元素並返回其值,如 LPOP queue:my-queue。處理空隊列:如果隊列為空,LPOP 返回 nil,可先檢查隊列是否存在再讀取元素。

centos redis如何配置Lua腳本執行時間 centos redis如何配置Lua腳本執行時間 Apr 14, 2025 pm 02:12 PM

在CentOS系統上,您可以通過修改Redis配置文件或使用Redis命令來限制Lua腳本的執行時間,從而防止惡意腳本佔用過多資源。方法一:修改Redis配置文件定位Redis配置文件:Redis配置文件通常位於/etc/redis/redis.conf。編輯配置文件:使用文本編輯器(例如vi或nano)打開配置文件:sudovi/etc/redis/redis.conf設置Lua腳本執行時間限制:在配置文件中添加或修改以下行,設置Lua腳本的最大執行時間(單位:毫秒)

redis命令行怎麼用 redis命令行怎麼用 Apr 10, 2025 pm 10:18 PM

使用 Redis 命令行工具 (redis-cli) 可通過以下步驟管理和操作 Redis:連接到服務器,指定地址和端口。使用命令名稱和參數向服務器發送命令。使用 HELP 命令查看特定命令的幫助信息。使用 QUIT 命令退出命令行工具。

redis計數器怎麼實現 redis計數器怎麼實現 Apr 10, 2025 pm 10:21 PM

Redis計數器是一種使用Redis鍵值對存儲來實現計數操作的機制,包含以下步驟:創建計數器鍵、增加計數、減少計數、重置計數和獲取計數。 Redis計數器的優勢包括速度快、高並發、持久性和簡單易用。它可用於用戶訪問計數、實時指標跟踪、遊戲分數和排名以及訂單處理計數等場景。

redis過期策略怎麼設置 redis過期策略怎麼設置 Apr 10, 2025 pm 10:03 PM

Redis數據過期策略有兩種:定期刪除:定期掃描刪除過期鍵,可通過 expired-time-cap-remove-count、expired-time-cap-remove-delay 參數設置。惰性刪除:僅在讀取或寫入鍵時檢查刪除過期鍵,可通過 lazyfree-lazy-eviction、lazyfree-lazy-expire、lazyfree-lazy-user-del 參數設置。

如何優化debian readdir的性能 如何優化debian readdir的性能 Apr 13, 2025 am 08:48 AM

在Debian系統中,readdir系統調用用於讀取目錄內容。如果其性能表現不佳,可嘗試以下優化策略:精簡目錄文件數量:盡可能將大型目錄拆分成多個小型目錄,降低每次readdir調用處理的項目數量。啟用目錄內容緩存:構建緩存機制,定期或在目錄內容變更時更新緩存,減少對readdir的頻繁調用。內存緩存(如Memcached或Redis)或本地緩存(如文件或數據庫)均可考慮。採用高效數據結構:如果自行實現目錄遍歷,選擇更高效的數據結構(例如哈希表而非線性搜索)存儲和訪問目錄信

See all articles