大話Redis進階

使用Redis過程當中,老是會遇到各類各樣問題,這裏進行問題的總結,做爲Redis 進階的經驗分享。redis


源碼


更新緩存的問題


[主動]須要操做人員去操做,或者定時調度
[被動]由用戶觸發更新
[預加載]提早加載好數據數據庫


  • 方案1
    • [主動]後臺點擊更新緩存按鈕,從DB查找最新數據集合,刪除原緩存數據,存儲新數據到緩存;
    • 問題:更新過程當中刪除掉緩存後恰好有業務在查詢,那麼這個時候返回的數據會是空,會影響用戶體驗

  • 方案2
    • [被動]前臺獲取數據時發現沒有緩存數據就會去數據庫同步數據到緩存
    • 問題:當併發請求獲取緩存數據不存在的時候,就會產生併發的查詢數據的操做。

  • 方案3
    • [主動]後臺點擊更新緩存按鈕,從DB查找最新數據集合,這裏不刪除緩存,經過遍歷數據覆蓋和刪除掉無效的數據
    • 問題:邏輯相對麻煩,並且更新機制沒法通用;

推薦


以上的幾種更新方案我都遇到過,由於產生了各類問題,因此我想到了一個相對好的方案,相似預加載功能,先把數據加載到緩存中,緩存成功後再切換顯示最新的數據,將舊數據設置過時;緩存

  • 方案4
    [主動][預加載]前臺獲取緩存的時候須要先獲得緩存數據對應的Redis Key(簡稱:[ShowingKey]),而後根據[ShowingKey]去讀取緩存數據(簡稱:[緩存];
    • 須要兩塊數據:
      • [ShowingKey](能夠是最近一次更新緩存的時間戳或者根據本身規則自定義)
      • [緩存](須要緩存的數據,如:DB數據等)

  • 舉個栗子:
    咱們如今有個業務須要緩存今日上新商品數據,緩存到Hash中服務器

    • [緩存]對應Redis Key 規則
      • Hash Key=Goods:Todays:{0} {0}=時間戳
    • [ShowingKey]對應的Redis Key
      • Key string key=Goods:Todays:ing 內容=最近一次的更新時間戳

    更新邏輯:併發

    後臺編輯人員操做完數據的時候點擊更新按鈕,獲取服務器當前時間=1469938351000=[更新時間戳],而後獲取DB數據,緩存到Goods:Todays:1469938351000中,添加緩存數據成功後,獲取Goods:Todays:ing中的時間戳1449538371020=[上一次更新時間戳],更新Goods:Todays:ing值=[更新時間戳]=1469938351000,更新成功後能夠把[上一次更新時間戳]對應的緩存設置過時時間,我通常是設置5秒後過時。(注意舊數據必定要設置過時時間,不能直接刪除,由於在切換[ShowingKey]的過程當中可能還有業務在使用)網站


更新總結


  • 第1種更新方案影響用戶體驗通常不推薦使用
  • 第2種更新方案能夠經過程序鎖,鎖住更新操做只能有一個進入DB查詢,能夠避免問題
  • 第3種更新方案不會有第1,2 的問題,可是更新邏輯寫起來比較麻煩,並且更新方案不能抽象通用
  • 第4種更新方案使用提早加載到緩存,而後在切換須要顯示的緩存數據,能夠完美解決1,2,3中的問題

redis內存不足,濫用


  • 問題
    1. 數據不斷累加,無效數據未清理,緩存未設置過時時間
    2. 存儲數據中包含未使用到字段,整個對象序列化到redis中
    3. 冷數據,或者根本不會再去使用的無效數據沒有清理
  • 解決
    1. 數據區分無效時間,設置過時時間,使無效數據過時;(如:經過日期後綴命名Key)
    2. 區分冷數據,清理掉冷數據;
    3. 緩存數據從簡,redis key命名從簡,數據字段命名從簡,無效字段不添加在緩存中;

鍵命名規範


  • 內存數據庫,鍵名長度影響有限內存空間,因此命名應該控制長度,簡短易懂;
  • 大小寫規範
  • 根據業務命名,相同業務統一的Key前綴

其餘經驗


  • 數值累加,get,set+1併發致使累加不許確.net

    • 使用redis increment 自增數值的機制不會有累加不許確的問題
  • .net 類庫 ServiceStack 3.9.71.0 的一個問題code

    SetEntryInHash 返回 bool,只有第一次新增的時候返回的是true,後面修改爲功了也都是返回false對象

    源碼:SetEntryInHash 方法,讀取hset的結果 判斷是否等於1,返回bool 源碼blog

    咱們經過命令: hset 第一次sflyq key不存在,添加成功返回的執行結果是:1 hset 第一次sflyq key已經存在,修改爲功購返回結果:0 源碼

    因此結果很明顯,經過SetEntryInHash 判斷hash是否key value 是否設置成功是有問題的,只有第一次設置會返回 ture


未完待續...
有補充的留言給我哦


感謝你們的支持,領取天貓【雙11紅包】,得到推廣費用來維持網站的運行,謝謝理解。

你們有啥意見或者建議的到 原文地址 給我留言吧,感謝支持~

相關文章
相關標籤/搜索