1. 程式人生 > >Redis使用過程中踩到的坑

Redis使用過程中踩到的坑

  1. redis(WRONGTYPE Operation against a key holding the wrong kind of value)

    前提是: key-list型別的資料,存為了key-value形式

    • 則使用rightPop取出列表資料時會報錯

    • 改為使用key-list存資料,依然會報錯

    解決方法: 刪除之前存錯格式的資料

  2. redis的管道操作

    Redis管道技術可以在服務端未響應時,客戶端繼續向服務端傳送請求,並最終一次性讀取所有服務端的響應。

    所有在管道內拿不到redis操作的值

  3. 使用scan代替keys (scan命令不能在管道中使用)

    因為keys命令會一次性地遍歷整個資料庫來獲取所有與給定模式相匹配的鍵,所以隨著資料庫包含的鍵值對越來越多,執行速度也會越來越慢

    scan命令以漸進的方式,分多次遍歷整個資料庫,並返回匹配給定模式的鍵。

    Redis的keys和scan命令.png

    scan命令使用的演算法可以保證,遍歷從開始到結束期間,一直存在於資料庫裡面的鍵肯定會被遍歷到。但中途被刪除或者中途新增的鍵是否會被遍歷到則是不確定的。另外,命令可能會返回同一個鍵多次。

  4. 對一個已經帶有過期時間的key執行 EXPIRE 命令,新指定的過期時間會取代舊的過期時間
    如果不希望在每次更新值的時候更新過期時間,可以在執行 expire 命令之前通過TTL 命令來判斷對應key是否已經設定了過期時間或是否過期。

    TTL 命令返回給定key的剩餘生存時間(秒),key不存在返回-2,key存在但沒有設定過期時間返回-1

    //RedisTemplate的getExpire內部封裝的就是TTL命令
    if (routerRedisTemplate.getExpire(key) < 0) {
       //設定100s的過期時間
    routerRedisTemplate.expire(key, 100, TimeUnit.SECONDS);
    }
  5. SET命令:如果key已經持有其他值,set會覆寫舊值,無視型別。
    如果不希望string型別覆蓋其他型別的RedisKey,可以在set之前通過TYPE 命令判斷key的型別

    if (routerRedisTemplate.hasKey(key) && Objects.equals(DataType.STRING,routerRedisTemplate.type(key))) {
                    addRedisStringKey(key, value, expireTime);
    }