使用Redis,你必須知道的21個注意要點

2022-01-08 Python中文社區
前言

最近在學習Redis相關知識,看了阿里的redis開發規範,以及Redis開發與運維這本書。分使用規範、有坑的命令、項目實戰操作、運維配置四個方向,整理了使用Redis的21個注意點,希望對大家有幫助,一起學習哈!

1、Redis的使用規範1.1、 key的規範要點

我們設計Redis的key的時候,要注意以下這幾個點:

❝以業務名為key前綴,用冒號隔開,以防止key衝突覆蓋。如,live:rank:1確保key的語義清晰的情況下,key的長度儘量小於30個字符。key禁止包含特殊字符,如空格、換行、單雙引號以及其他轉義字符。Redis的key儘量設置ttl,以保證不使用的Key能被及時清理或淘汰。❞1.2、value的規範要點

Redis的value值不可以隨意設置的哦。

「第一點」,如果大量存儲bigKey是會有問題的,會導致慢查詢,內存增長過快等等。

如果是String類型,單個value大小控制10k以內。如果是hash、list、set、zset類型,元素個數一般不超過5000。

「第二點」,要選擇適合的數據類型。不少小夥伴只用Redis的String類型,上來就是set和get。實際上,Redis 提供了「豐富的數據結構類型」,有些業務場景,更適合hash、zset等其他數據結果。

「反例:」

set user:666:name jay
set user:666:age 18

「正例」

hmset user:666 name jay age 18 

1.3. 給Key設置過期時間,同時注意不同業務的key,儘量過期時間分散一點因為Redis的數據是存在內存中的,而內存資源是很寶貴的。我們一般是把Redis當做緩存來用,而「不是資料庫」,所以key的生命周期就不宜太長久啦。因此,你的key,一般建議用「expire設置過期時間」

如果大量的key在某個時間點集中過期,到過期的那個時間點,Redis可能會存在卡頓,甚至出現「緩存雪崩」現象,因此一般不同業務的key,過期時間應該分散一些。有時候,同業務的,也可以在時間上加一個隨機值,讓過期時間分散一些。

1.4.建議使用批量操作提高效率

我們日常寫SQL的時候,都知道,批量操作效率會更高,一次更新50條,比循環50次,每次更新一條效率更高。其實Redis操作命令也是這個道理。

Redis客戶端執行一次命令可分為4個過程:1.發送命令-> 2.命令排隊-> 3.命令執行-> 4. 返回結果。1和4 稱為RRT(命令執行往返時間)。Redis提供了「批量操作命令,如mget、mset」等,可有效節約RRT。但是呢,大部分的命令,是不支持批量操作的,比如hgetall,並沒有mhgetall存在。「Pipeline」 則可以解決這個問題。

Pipeline是什麼呢?它能將一組Redis命令進行組裝,通過一次RTT傳輸給Redis,再將這組Redis命令的執行結果按順序返回給客戶端.

我們先來看下沒有使用Pipeline執行了n條命令的模型:

使用Pipeline執行了n次命令,整個過程需要1次RTT,模型如下:

2、Redis 有坑的那些命令2.1. 慎用O(n)複雜度命令,如hgetall、smember,lrange等

因為Redis是單線程執行命令的。hgetall、smember等命令時間複雜度為O(n),當n持續增加時,會導致 Redis CPU 持續飆高,阻塞其他命令的執行。

hgetall、smember,lrange等這些命令不是一定不能使用,需要綜合評估數據量,明確n的值,再去決定。比如hgetall,如果哈希元素n比較多的話,可以優先考慮使用「hscan」

❞2.2  慎用Redis的monitor命令

Redis Monitor 命令用於實時列印出Redis伺服器接收到的命令,如果我們想知道客戶端對redis服務端做了哪些命令操作,就可以用Monitor 命令查看,但是它一般「調試」用而已,儘量不要在生產上用!因為「monitor命令可能導致redis的內存持續飆升。」

monitor的模型是醬紫的,它會將所有在Redis伺服器執行的命令進行輸出,一般來講Redis伺服器的QPS是很高的,也就是如果執行了monitor命令,Redis伺服器在Monitor這個客戶端的輸出緩衝區又會有大量「存貨」,也就佔用了大量Redis內存。

2.3、生產環境不能使用 keys指令

Redis Keys 命令用於查找所有符合給定模式pattern的key。如果想查看Redis 某類型的key有多少個,不少小夥伴想到用keys命令,如下:

keys key前綴*

但是,redis的keys是遍歷匹配的,複雜度是O(n),資料庫數據越多就越慢。我們知道,redis是單線程的,如果數據比較多的話,keys指令就會導致redis線程阻塞,線上服務也會停頓了,直到指令執行完,服務才會恢復。因此,「一般在生產環境,不要使用keys指令」。官方文檔也有聲明:

Warning: consider KEYS as a command that should only be used in production environments with extreme care. It may ruin performance when it is executed against large databases. This command is intended for debugging and special operations, such as changing your keyspace layout. Don't use KEYS in your regular application code. If you're looking for a way to find keys in a subset of your keyspace, consider using sets.

其實,可以使用scan指令,它同keys命令一樣提供模式匹配功能。它的複雜度也是 O(n),但是它通過遊標分步進行,「不會阻塞redis線程」;但是會有一定的「重複概率」,需要在「客戶端做一次去重」

scan支持增量式迭代命令,增量式迭代命令也是有缺點的:舉個例子, 使用 SMEMBERS 命令可以返回集合鍵當前包含的所有元素, 但是對於 SCAN 這類增量式迭代命令來說, 因為在對鍵進行增量式迭代的過程中, 鍵可能會被修改, 所以增量式迭代命令只能對被返回的元素提供有限的保證 。

❞2.4 禁止使用flushall、flushdb❝Flushall 命令用於清空整個 Redis 伺服器的數據(刪除所有資料庫的所有 key )。Flushdb 命令用於清空當前資料庫中的所有 key。❞

這兩命令是原子性的,不會終止執行。一旦開始執行,不會執行失敗的。

2.5 注意使用del命令

刪除key你一般使用什麼命令?是直接del?如果刪除一個key,直接使用del命令當然沒問題。但是,你想過del的時間複雜度是多少嘛?我們分情況探討一下:

如果刪除一個String類型的key,時間複雜度就是O(1),「可以直接del」。如果刪除一個List/Hash/Set/ZSet類型時,它的複雜度是O(n), n表示元素個數。

因此,如果你刪除一個List/Hash/Set/ZSet類型的key時,元素越多,就越慢。「當n很大時,要尤其注意」,會阻塞主線程的。那麼,如果不用del,我們應該怎麼刪除呢?

❝如果是List類型,你可以執行lpop或者rpop,直到所有元素刪除完成。如果是Hash/Set/ZSet類型,你可以先執行hscan/sscan/scan查詢,再執行hdel/srem/zrem依次刪除每個元素。❞2.6 避免使用SORT、SINTER等複雜度過高的命令。

執行複雜度較高的命令,會消耗更多的 CPU 資源,會阻塞主線程。所以你要避免執行如SORT、SINTER、SINTERSTORE、ZUNIONSTORE、ZINTERSTORE等聚合命令,一般建議把它放到客戶端來執行。

3、項目實戰避坑操作3.1 分布式鎖使用的注意點

分布式鎖其實就是,控制分布式系統不同進程共同訪問共享資源的一種鎖的實現。秒殺下單、搶紅包等等業務場景,都需要用到分布式鎖。我們經常使用Redis作為分布式鎖,主要有這些注意點:

3.1.1 兩個命令SETNX + EXPIRE分開寫(典型錯誤實現範例)
if(jedis.setnx(key_resource_id,lock_value) == 1){ //加鎖
    expire(key_resource_id,100); //設置過期時間
    try {
        do something  //業務請求
    }catch(){
  }
  finally {
       jedis.del(key_resource_id); //釋放鎖
    }
}

如果執行完setnx加鎖,正要執行expire設置過期時間時,進程crash或者要重啟維護了,那麼這個鎖就「長生不老」了,「別的線程永遠獲取不到鎖」啦,所以一般分布式鎖不能這麼實現。

3.1.2 SETNX + value值是過期時間 (有些小夥伴是這麼實現,有坑)
long expires = System.currentTimeMillis() + expireTime; //系統時間+設置的過期時間
String expiresStr = String.valueOf(expires);

// 如果當前鎖不存在,返回加鎖成功
if (jedis.setnx(key_resource_id, expiresStr) == 1) {
        return true;

// 如果鎖已經存在,獲取鎖的過期時間
String currentValueStr = jedis.get(key_resource_id);

// 如果獲取到的過期時間,小於系統當前時間,表示已經過期
if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {

     // 鎖已過期,獲取上一個鎖的過期時間,並設置現在鎖的過期時間(不了解redis的getSet命令的小夥伴,可以去官網看下哈)
    String oldValueStr = jedis.getSet(key_resource_id, expiresStr);
    
    if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
         // 考慮多線程並發的情況,只有一個線程的設置值和當前值相同,它才可以加鎖
         return true;
    }
}
        
//其他情況,均返回加鎖失敗
return false;
}

這種方案的「缺點」

❝過期時間是客戶端自己生成的,分布式環境下,每個客戶端的時間必須同步沒有保存持有者的唯一標識,可能被別的客戶端釋放/解鎖。鎖過期的時候,並發多個客戶端同時請求過來,都執行了jedis.getSet(),最終只能有一個客戶端加鎖成功,但是該客戶端鎖的過期時間,可能被別的客戶端覆蓋。❞3.1.3:SET的擴展命令(SET EX PX NX)(注意可能存在的問題)
if(jedis.set(key_resource_id, lock_value, "NX", "EX", 100s) == 1){ //加鎖
    try {
        do something  //業務處理
    }catch(){
  }
  finally {
       jedis.del(key_resource_id); //釋放鎖
    }
}

這個方案還是可能存在問題:

3.1.4 SET EX PX NX + 校驗唯一隨機值,再刪除(解決了誤刪問題,還是存在鎖過期,業務沒執行完的問題)
if(jedis.set(key_resource_id, uni_request_id, "NX", "EX", 100s) == 1){ //加鎖
    try {
        do something  //業務處理
    }catch(){
  }
  finally {
       //判斷是不是當前線程加的鎖,是才釋放
       if (uni_request_id.equals(jedis.get(key_resource_id))) {
        jedis.del(lockKey); //釋放鎖
        }
    }
}

在這裡,判斷是不是當前線程加的鎖和釋放鎖不是一個原子操作。如果調用jedis.del()釋放鎖的時候,可能這把鎖已經不屬於當前客戶端,會解除他人加的鎖。

一般也是用lua腳本代替。lua腳本如下:

if redis.call('get',KEYS[1]) == ARGV[1] then 
   return redis.call('del',KEYS[1]) 
else
   return 0
end;

3.1.5 Redisson框架 + Redlock算法 解決鎖過期釋放,業務沒執行完問題+單機問題

Redisson 使用了一個Watch dog解決了鎖過期釋放,業務沒執行完問題,Redisson原理圖如下:

以上的分布式鎖,還存在單機問題:

如果線程一在Redis的master節點上拿到了鎖,但是加鎖的key還沒同步到slave節點。恰好這時,master節點發生故障,一個slave節點就會升級為master節點。線程二就可以獲取同個key的鎖啦,但線程一也已經拿到鎖了,鎖的安全性就沒了。

針對單機問題,可以使用Redlock算法。有興趣的朋友可以看下我這篇文章哈,七種方案!探討Redis分布式鎖的正確使用姿勢

3.2 緩存一致性注意點一致性要求高的話,可以使用biglog+MQ保證。

有興趣的朋友,可以看下我這篇文章哈:並發環境下,先操作資料庫還是先操作緩存?

3.3 合理評估Redis容量,避免由於頻繁set覆蓋,導致之前設置的過期時間無效。

我們知道,Redis的所有數據結構類型,都是可以設置過期時間的。假設一個字符串,已經設置了過期時間,你再去重新設置它,就會導致之前的過期時間無效。

Redis setKey源碼如下:

void setKey(redisDb *db,robj *key,robj *val) {
    if(lookupKeyWrite(db,key)==NULL) {
       dbAdd(db,key,val);
    }else{
    dbOverwrite(db,key,val);
    }
    incrRefCount(val);
    removeExpire(db,key); //去掉過期時間
    signalModifiedKey(db,key);
}

實際業務開發中,同時我們要合理評估Redis的容量,避免頻繁set覆蓋,導致設置了過期時間的key失效。新手小白容易犯這個錯誤。

3.4 緩存穿透問題

先來看一個常見的緩存使用方式:讀請求來了,先查下緩存,緩存有值命中,就直接返回;緩存沒命中,就去查資料庫,然後把資料庫的值更新到緩存,再返回。

「緩存穿透」:指查詢一個一定不存在的數據,由於緩存是不命中時需要從資料庫查詢,查不到數據則不寫入緩存,這將導致這個不存在的數據每次請求都要到資料庫去查詢,進而給資料庫帶來壓力。

通俗點說,讀請求訪問時,緩存和資料庫都沒有某個值,這樣就會導致每次對這個值的查詢請求都會穿透到資料庫,這就是緩存穿透。

緩存穿透一般都是這幾種情況產生的:

「業務不合理的設計」,比如大多數用戶都沒開守護,但是你的每個請求都去緩存,查詢某個userid查詢有沒有守護。「業務/運維/開發失誤的操作」,比如緩存和資料庫的數據都被誤刪除了。「黑客非法請求攻擊」,比如黑客故意捏造大量非法請求,以讀取不存在的業務數據。

「如何避免緩存穿透呢?」 一般有三種方法。

如果是非法請求,我們在API入口,對參數進行校驗,過濾非法值。如果查詢資料庫為空,我們可以給緩存設置個空值,或者默認值。但是如有有寫請求進來的話,需要更新緩存哈,以保證緩存一致性,同時,最後給緩存設置適當的過期時間。(業務上比較常用,簡單有效)使用布隆過濾器快速判斷數據是否存在。即一個查詢請求過來時,先通過布隆過濾器判斷值是否存在,存在才繼續往下查。❝

布隆過濾器原理:它由初始值為0的位圖數組和N個哈希函數組成。一個對一個key進行N個hash算法獲取N個值,在比特數組中將這N個值散列後設定為1,然後查的時候如果特定的這幾個位置都為1,那麼布隆過濾器判斷該key存在。

❞3.5 緩存雪奔問題

「緩存雪奔:」 指緩存中數據大批量到過期時間,而查詢數據量巨大,請求都直接訪問資料庫,引起資料庫壓力過大甚至down機。

緩存雪奔一般是由於大量數據同時過期造成的,對於這個原因,可通過均勻設置過期時間解決,即讓過期時間相對離散一點。如採用一個較大固定值+一個較小的隨機值,5小時+0到1800秒醬紫。Redis 故障宕機也可能引起緩存雪奔。這就需要構造Redis高可用集群啦。3.6 緩存擊穿問題

「緩存擊穿:」 指熱點key在某個時間點過期的時候,而恰好在這個時間點對這個Key有大量的並發請求過來,從而大量的請求打到db。

緩存擊穿看著有點像,其實它兩區別是,緩存雪奔是指資料庫壓力過大甚至down機,緩存擊穿只是大量並發請求到了DB資料庫層面。可以認為擊穿是緩存雪奔的一個子集吧。有些文章認為它倆區別,是區別在於擊穿針對某一熱點key緩存,雪奔則是很多key。

解決方案就有兩種:

「1.使用互斥鎖方案」。緩存失效時,不是立即去加載db數據,而是先使用某些帶成功返回的原子操作命令,如(Redis的setnx)去操作,成功的時候,再去加載db資料庫數據和設置緩存。否則就去重試獲取緩存。「2. 「永不過期」」,是指沒有設置過期時間,但是熱點數據快要過期時,異步線程去更新和設置過期時間。3.7、緩存熱key問題

在Redis中,我們把訪問頻率高的key,稱為熱點key。如果某一熱點key的請求到伺服器主機時,由於請求量特別大,可能會導致主機資源不足,甚至宕機,從而影響正常的服務。

而熱點Key是怎麼產生的呢?主要原因有兩個:

❝用戶消費的數據遠大於生產的數據,如秒殺、熱點新聞等讀多寫少的場景。請求分片集中,超過單Redi伺服器的性能,比如固定名稱key,Hash落入同一臺伺服器,瞬間訪問量極大,超過機器瓶頸,產生熱點Key問題。❞

那麼在日常開發中,如何識別到熱點key呢?

❝❞

如何解決熱key問題?

❝對熱key進行hash散列,比如將一個key備份為key1,key2……keyN,同樣的數據N個備份,N個備份分布到不同分片,訪問時可隨機訪問N個備份中的一個,進一步分擔讀流量;使用二級緩存,即JVM本地緩存,減少Redis的讀請求。❞4. Redis配置運維4.1 使用長連接而不是短連接,並且合理配置客戶端的連接池如果使用短連接,每次都需要過 TCP 三次握手、四次揮手,會增加耗時。然而長連接的話,它建立一次連接,redis的命令就能一直使用,醬紫可以減少建立redis連接時間。連接池可以實現在客戶端建立多個連接並且不釋放,需要使用連接的時候,不用每次都創建連接,節省了耗時。但是需要合理設置參數,長時間不操作 Redis時,也需及時釋放連接資源。4.2 只使用 db0

Redis-standalone架構禁止使用非db0.原因有兩個

一個連接,Redis執行命令select 0和select 1切換,會損耗新能。Redis Cluster 只支持 db0,要遷移的話,成本高4.3 設置maxmemory + 恰當的淘汰策略。

為了防止內存積壓膨脹。比如有些時候,業務量大起來了,redis的key被大量使用,內存直接不夠了,運維小哥哥也忘記加大內存了。難道redis直接這樣掛掉?所以需要根據實際業務,選好maxmemory-policy(最大內存淘汰策略),設置好過期時間。一共有8種內存淘汰策略:

volatile-lru:當內存不足以容納新寫入數據時,從設置了過期時間的key中使用LRU(最近最少使用)算法進行淘汰;allkeys-lru:當內存不足以容納新寫入數據時,從所有key中使用LRU(最近最少使用)算法進行淘汰。volatile-lfu:4.0版本新增,當內存不足以容納新寫入數據時,在過期的key中,使用LFU算法進行刪除key。allkeys-lfu:4.0版本新增,當內存不足以容納新寫入數據時,從所有key中使用LFU算法進行淘汰;volatile-random:當內存不足以容納新寫入數據時,從設置了過期時間的key中,隨機淘汰數據;。allkeys-random:當內存不足以容納新寫入數據時,從所有key中隨機淘汰數據。volatile-ttl:當內存不足以容納新寫入數據時,在設置了過期時間的key中,根據過期時間進行淘汰,越早過期的優先被淘汰;noeviction:默認策略,當內存不足以容納新寫入數據時,新寫入操作會報錯。4.4 開啟 lazy-free 機制

Redis4.0+版本支持lazy-free機制,如果你的Redis還是有bigKey這種玩意存在,建議把lazy-free開啟。當開啟它後,Redis 如果刪除一個 bigkey 時,釋放內存的耗時操作,會放到後臺線程去執行,減少對主線程的阻塞影響。

參考與感謝Reference[1]

Redis 千萬不要亂用KEYS命令,不然會挨打的:https://www.cnblogs.com/tonyY/p/12175032.html

[2]

阿里雲Redis開發規範:https://developer.aliyun.com/article/531067

[3]

Redis的緩存穿透及解決方法——布隆過濾器BloomFilter:https://blog.csdn.net/wx1528159409/article/details/88357728

[4]

Redis 緩存性能實踐及總結:https://www.shangmayuan.com/a/d2f178b548a64c25854a9750.html

相關焦點

  • Redis 使用的 10 個小技巧
    隨之而來的一系列最佳實踐,使得大多數人可以正確地使用 Redis。下面我們將探索正確使用 Redis 的10個技巧。很多時候人們跑到我這裡,他們想知道為什麼自己的Redis-Benchmark統計的結果低於最優結果 。但我們必須要把各種不同的真實情況考慮進來,例如:Redis-Benchmark的測試結果提供了一個保證你的 Redis-Server 不會運行在非正常狀態下的基準點,但是你永遠不要把它作為一個真實的「壓力測試」。
  • 走進 Redis:Redis 的安裝、使用以及集群的搭建
    /redis-server redis.conf運行redis。這樣redis就後臺運行了,我們可以使用 ps aux|grep redis來查看redis的運行狀態:900秒(15分鐘)之內至少有1個KEY進行了改變300秒(5分鐘)之內至少有10個KEY進行了改變60秒(1分鐘)之內至少有10000個KEY進行了改變aof形式:append only file。把所有對redis資料庫操作的命令,增刪改操作的命令。保存到文件中。資料庫恢復時把所有的命令執行一遍即可。
  • Spring Data Redis使用
    環境搭建要使用SDR,首先需要搭建Spring+SpringMVC環境,由於這個不是本文的重點,因此這一步我直接略過,Spring+SpringMVC環境搭建成功後,接下來我們要整合SDR,首先需要添加如下依賴:<dependency><groupId>redis.clients</groupId><artifactId>
  • Redis,常見的 9 種使用場景
    大家好,我是掃地僧,每天 21:00 點,分享 Java 精選文章,咱們不見不散!本文將介紹 redis 常見的 9 種使用場景。2、限時業務的運用redis 中可以使用 expire 命令設置一個鍵的生存時間,到時間後 redis 會刪除它。利用這一特性可以運用在限時的優惠活動信息、手機驗證碼等業務場景。
  • Redis精進:List的使用和應用場景
    作者:銳玩道juejin.im/post/5df77d8bf265da33f718b654最近在精進學習Redis,邊學邊寫一、List類型使用說明注意它是鍊表而不是數組。擴展:Redis面試連環問,快看看你能走到哪一步!三、使用場景:鍊表用來做異步隊列鍊表常用來做異步隊列使用將需要延後處理的任務結構體序列化(JSON)成字符串塞進 Redis 的列表另一個線程從這個列表中輪詢數據進行處理。
  • Golang 官方推薦使用的 Redis 客戶端 redigo
    go-redis 三方庫為我們封裝了很多函數來執行 Redis 命令,而 redigo 三方庫只有一個 Do 函數執行 Redis 命令,更接近使用 redis-cli 操作 Redis,這一點是我個人比較喜歡的,只要熟悉 Redis,就可以輕鬆使用 redigo 作為客戶端操作 Redis,而不需要再去記三方庫封裝的函數。
  • Redis幾個重要的健康指標
    連接數連接的客戶端數量,可通過命令src/redis-cli info Clients | grep connected_clients得到,這個值跟使用redis的服務的連接池配置關係比較大,所以在監控這個欄位的值時需要注意。另外這個值也不能太大,建議不要超過5000,如果太大可能是redis處理太慢,那麼需要排除問題找出原因。
  • Python使用redis存儲對象
    Python總的對象存儲到redis中默認為字符串,那麼如何存儲對象呢?下面就看看如何直接將Python中對象存儲到redis中先寫個測試redis是否正常連接上import rediscache = redis.StrictRedis('172.20.0.227',6379)
  • Redis的3個高級數據結構
    三個操作bits組的命令如下:bitmaps一般的使用場景:例如,想像一下你想知道訪問你的網站的用戶的最長連續時間。你開始計算從0開始的天數,就是你的網站公開的那天,每次用戶訪問網站時通過SETBIT命令設置bit為1,可以簡單的用當前時間減去初始時間並除以3600*24(結果就是你的網站公開的第幾天)當做這個bit的位置。
  • laravel框架中使用redis
    一、簡介Redis是一個nosql資料庫,現在用的比較多,PHP中直接操作redis大家都很熟悉了,在laravel中如何操作redis呢?本專題內容來講解。二、特性redis是一個key-value存儲系統。
  • 架構秘笈:移花接木,使用MySQL模擬Redis
    這年頭,你看到的東西未必就是你認為的東西。一個mysql協議的後面,可能是tidb;一個linux機器後面,可能是一個精簡的docker;你覺得xjjdog是個女的,但可能ta自己也不太清楚;而當你大呼php萬歲的時候,可能是研發人員和你開個玩笑,重寫了後綴,而後端用的卻是java。
  • redis五大數據類型使用場景
    下一個請求落在B伺服器上,想要從session中獲取用戶信息就不能正常獲取了,因為用戶信息的session在伺服器A上,為了解決這個問題,使用redis集中管理這些session,將session存入redis,使用的時候直接從redis中獲取就可以了。
  • 在Kubernetes上部署一套 Redis 集群
    註:redis-cluster相關的背景知識和細節在此不做贅述一、問題分析本質上來說,在k8s上部署一個redis集群和部署一個普通應用沒有什麼太大的區別,但需要注意下面幾個問題:Redis是一個有狀態應用這是部署redis集群時我們最需要注意的問題,當我們把redis以pod的形式部署在k8s中時,每個pod
  • 在Redis中使用簡單強大的Lua腳本
    但有個問題就是setnx+expire不是原子性的,有可能獲取到鎖後,還沒執行expire命令,也沒執行釋放鎖的操作,服務就掛了,這樣這個資源就永遠也不會訪問到了。為了解決這個問題,Redis 2.6.12版本以後,為set命令增加了一系列的參數,我們此時用NX和PX參數就可以解決這個問題。
  • REDIS 如何利用python 操作redis 集群 (投稿文章)
    ,redis的使用往往涉及高並發,每次都重新創建連接不是我們所建議的方式,我們可以使用連接池來創建連接,並通過多線程來進行訪問。,然後開啟10個線程,為了顯示的不太難看,我們在print的地方加了個鎖,我們期待這個樣能夠正常的10個線程同時向redis裡面寫數據,但是實際卻發現!
  • Redis的簡單入門
    Redis 與其他 key - value 緩存產品有以下三個特點:Redis支持數據的持久化,可以將內存中的數據保存在磁碟中,重啟的時候可以再次加載進行使用。Redis不僅僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
  • Redlock:Redis分布式鎖最牛逼的實現
    普通實現說道Redis分布式鎖大部分人都會想到:setnx+lua,或者知道set key value px milliseconds nx。Redlock實現antirez提出的redlock算法大概是這樣的:在Redis的分布式環境中,我們假設有N個Redis master。這些節點完全互相獨立,不存在主從複製或者其他集群協調機制。我們確保將在N個實例上使用與在Redis單實例下相同方法獲取和釋放鎖。
  • Redis緩存與NodeJS的初學教程
    雖然它最流行的用例是緩存,Redis還有很多其他用例,你可以利用它的快閃記憶體資料庫的快得驚人。在這個教程中,我們將給你一個快速介紹Redis。我們還將使用Redis為節點應用程式創建一個簡單的緩存,看看它是如何影響其性能的。
  • Redis哨兵是個啥?實現高可用的秘密原來在這裡
    哨兵模式配置我本地 Redis 安裝目錄:/usr/local/rediscp sentinel.conf  /usr/local/redis/etc哨兵使用的配置文件是 sentinel.conf,我們來解讀下這個配置文件,看看需要做什麼?
  • redis 過期策略
    假設 redis 裡放了 10w 個 key,都設置了過期時間,你每隔幾百毫秒,就檢查 10w 個 key,那 redis 基本上就死了,cpu 負載會很高的,消耗在你的檢查過期 key 上了。注意,這裡可不是每隔 100ms 就遍歷所有的設置過期時間的 key,那樣就是一場性能上的災難。實際上 redis 是每隔 100ms 隨機抽取一些 key 來檢查和刪除的。