一、分析記憶體
首先,需要弄清楚,是哪些業務資料佔用了大量redis。SCAN命令可以按正則來匹配Key,結合目前編碼習慣,基本都是以"#",":"分隔的key,例如使用者資料統一的key字首為us:{userId}。這樣就可以直接用SCAN命令查出各個業務資料的redis key數量、佔用的記憶體(透過debug obejct得到serializedlength)、過期時間。
所以這樣就寫了redis-memory-analysis 求star go-redis-memory-analysis 求star,分析記憶體佔用,將結果匯出到csv檔案。
再根據key字首定位到業務程式碼,清理或遷移資料至其他地方。
這種統計方式有個缺點,耗時很久,比如千萬的key,需要6小時才能掃完。
再結合--bigkeys引數找出redis中最大的key
redis-cli --bigkeys
二、Redis maxmemory與maxmemory-policy
maxmemory設定最大記憶體,達到最大記憶體設定後,redis根據maxmemory-policy配置的策略來清理資料 釋放空間
maxmemory-policy:
noeviction:返回錯誤當記憶體限制達到並且客戶端嘗試執行會讓更多記憶體被使用的命令(大部分的寫入指令,但DEL和幾個例外) r> allkeys-lru: 嘗試回收最少使用的鍵(LRU),使得新新增的資料有空間存放。
volatile-lru: 嘗試回收最少使用的鍵(LRU),但僅限於在過期集合的鍵,使得新新增的資料有空間存放。
allkeys-random: 回收隨機的鍵使得新新增的資料有空間存放。
volatile-random: 回收隨機的鍵使得新新增的資料有空間存放,但僅限於在過期集合的鍵。
volatile-ttl: 回收在過期集合的鍵,並且優先回收存活時間(TTL)較短的鍵,使得新新增的資料有空間存放。
如果沒有鍵滿足回收的前提條件的話,策略volatile-lru, volatile-random以及volatile-ttl就和noeviction 差不多了。
選擇正確的回收策略是非常重要的,這取決於你的應用的訪問模式,不過你可以在執行時進行相關的策略調整,並且監控快取命中率和沒命中的次數,透過RedisINFO命令輸出以便調優。
一般的經驗規則:
使用allkeys-lru策略:當你希望你的請求符合一個冪定律分佈,也就是說,你希望部分的子集元素將比其它其它元素被訪問的更多。如果你不確定選擇什麼,這是個很好的選擇。.
使用allkeys-random:如果你是迴圈訪問,所有的鍵被連續的掃描,或者你希望請求分佈正常(所有元素被訪問的機率都差不多)。
使用volatile-ttl:如果你想要透過建立快取物件時設定TTL值,來決定哪些物件應該被過期。
allkeys-lru 和 volatile-random策略對於當你想要單一的例項實現快取及持久化一些鍵時很有用。不過一般執行兩個例項是解決這個問題的更好方法。
為了鍵設定過期時間也是需要消耗記憶體的,所以使用allkeys-lru這種策略更加高效,因為沒有必要為鍵取設定過期時間當記憶體有壓力時。
一、分析記憶體
首先,需要弄清楚,是哪些業務資料佔用了大量redis。SCAN命令可以按正則來匹配Key,結合目前編碼習慣,基本都是以"#",":"分隔的key,例如使用者資料統一的key字首為us:{userId}。這樣就可以直接用SCAN命令查出各個業務資料的redis key數量、佔用的記憶體(透過debug obejct得到serializedlength)、過期時間。
所以這樣就寫了redis-memory-analysis 求star go-redis-memory-analysis 求star,分析記憶體佔用,將結果匯出到csv檔案。
再根據key字首定位到業務程式碼,清理或遷移資料至其他地方。
這種統計方式有個缺點,耗時很久,比如千萬的key,需要6小時才能掃完。
再結合--bigkeys引數找出redis中最大的key
redis-cli --bigkeys
二、Redis maxmemory與maxmemory-policy
maxmemory設定最大記憶體,達到最大記憶體設定後,redis根據maxmemory-policy配置的策略來清理資料 釋放空間
maxmemory-policy:
noeviction:返回錯誤當記憶體限制達到並且客戶端嘗試執行會讓更多記憶體被使用的命令(大部分的寫入指令,但DEL和幾個例外) r> allkeys-lru: 嘗試回收最少使用的鍵(LRU),使得新新增的資料有空間存放。
volatile-lru: 嘗試回收最少使用的鍵(LRU),但僅限於在過期集合的鍵,使得新新增的資料有空間存放。
allkeys-random: 回收隨機的鍵使得新新增的資料有空間存放。
volatile-random: 回收隨機的鍵使得新新增的資料有空間存放,但僅限於在過期集合的鍵。
volatile-ttl: 回收在過期集合的鍵,並且優先回收存活時間(TTL)較短的鍵,使得新新增的資料有空間存放。
如果沒有鍵滿足回收的前提條件的話,策略volatile-lru, volatile-random以及volatile-ttl就和noeviction 差不多了。
選擇正確的回收策略是非常重要的,這取決於你的應用的訪問模式,不過你可以在執行時進行相關的策略調整,並且監控快取命中率和沒命中的次數,透過RedisINFO命令輸出以便調優。
一般的經驗規則:
使用allkeys-lru策略:當你希望你的請求符合一個冪定律分佈,也就是說,你希望部分的子集元素將比其它其它元素被訪問的更多。如果你不確定選擇什麼,這是個很好的選擇。.
使用allkeys-random:如果你是迴圈訪問,所有的鍵被連續的掃描,或者你希望請求分佈正常(所有元素被訪問的機率都差不多)。
使用volatile-ttl:如果你想要透過建立快取物件時設定TTL值,來決定哪些物件應該被過期。
allkeys-lru 和 volatile-random策略對於當你想要單一的例項實現快取及持久化一些鍵時很有用。不過一般執行兩個例項是解決這個問題的更好方法。
為了鍵設定過期時間也是需要消耗記憶體的,所以使用allkeys-lru這種策略更加高效,因為沒有必要為鍵取設定過期時間當記憶體有壓力時。