一、redis的併發競爭問題如何解決?
redis為單程序單執行緒模式,採用佇列模式將併發訪問變為序列訪問。redis本身沒有鎖的概念,redis對於多個客戶端連線並不存在競爭,但是在jedis客戶端對redis進行併發訪問時會發生連線超時、資料轉換錯誤、阻塞、客戶端關閉連線等問題,這些問題均是由於客戶端連線混亂造成。對此有2種解決方法:
1.客戶端角度,為保證每個客戶端間正常有序與redis進行通訊,對連線進行池化,同時對客戶端讀寫redis操作採用內部鎖synchronized。
2.伺服器角度,利用setnx實現鎖。
對於第一種,需要應用程式自己處理資源的同步,可以使用的方法比較通俗,可以使用synchronized也可以使用lock;第二種需要用到redis的setnx命令,但是需要注意一些問題
二、redis的快取失效策略和主鍵失效機制
作為快取系統都要定期清理無效資料,就需要乙個主鍵失效和淘汰策略.
在redis當中,有生存期的key被稱為volatile。在建立快取時,要為給定的key設定生存期,當key過期的時候(生存期為0),它可能會被刪除。
1、影響生存時間的一些操作
生存時間可以通過使用 del 命令來刪除整個 key 來移除,或者被 set 和 getset 命令覆蓋原來的資料,也就是說,修改key對應的value和使用另外相同的key和value來覆蓋以後,當前資料的生存時間不同。
比如說,對乙個 key 執行incr命令,對乙個列表進行lpush命令,或者對乙個雜湊表執行hset命令,這類操作都不會修改 key 本身的生存時間。另一方面,如果使用rename對乙個 key 進行改名,那麼改名後的 key的生存時間和改名前一樣。
rename命令的另一種可能是,嘗試將乙個帶生存時間的 key 改名成另乙個帶生存時間的 another_key ,這時舊的 another_key (以及它的生存時間)會被刪除,然後舊的 key 會改名為 another_key ,因此,新的 another_key 的生存時間也和原本的 key 一樣。使用persist命令可以在不刪除 key 的情況下,移除 key 的生存時間,讓 key 重新成為乙個persistent key 。
2、如何更新生存時間
可以對乙個已經帶有生存時間的 key 執行expire命令,新指定的生存時間會取代舊的生存時間。過期時間的精度已經被控制在1ms之內,主鍵失效的時間複雜度是o(1),
expire和ttl命令搭配使用,ttl可以檢視key的當前生存時間。設定成功返回 1;當 key 不存在或者不能為 key 設定生存時間時,返回 0 。
最大快取配置
在 redis 中,允許使用者設定最大使用記憶體大小
server.maxmemory
預設為0,沒有指定最大快取,如果有新的資料新增,超過最大記憶體,則會使redis崩潰,所以一定要設定。redis 記憶體資料集大小上公升到一定大小的時候,就會實行資料淘汰策略。
redis 提供 6種資料淘汰策略:
. volatile-lru:從已設定過期時間的資料集(server.db[i].expires)中挑選最近最少使用的資料淘汰
. volatile-ttl:從已設定過期時間的資料集(server.db[i].expires)中挑選將要過期的資料淘汰
. volatile-random:從已設定過期時間的資料集(server.db[i].expires)中任意選擇資料淘汰
. allkeys-lru:從資料集(server.db[i].dict)中挑選最近最少使用的資料淘汰
. allkeys-random:從資料集(server.db[i].dict)中任意選擇資料淘汰
. no-enviction(驅逐):禁止驅逐資料
注意這裡的6種機制,volatile和allkeys規定了是對已設定過期時間的資料集淘汰資料還是從全部資料集淘汰資料,後面的lru、ttl以及random是三種不同的淘汰策略,再加上一種no-enviction永不**的策略。
使用策略規則:
1、如果資料呈現冪律分布,也就是一部分資料訪問頻率高,一部分資料訪問頻率低,則使用allkeys-lru
2、如果資料呈現平等分布,也就是所有的資料訪問頻率都相同,則使用allkeys-random
三種資料淘汰策略:
ttl和random比較容易理解,實現也會比較簡單。主要是lru最近最少使用淘汰策略,設計上會對key 按失效時間排序,然後取最先失效的key進行淘汰
redis佇列一些問題
將所有指定的值插入到存於 key 的列表的頭部。如果 key 不存在,那麼在進行 push 操作前會建立乙個空列表。如果 key 對應的值不是乙個 list 的話,那麼會返回乙個錯誤。php 示例 public function push k,value else 可以使用乙個命令把多個元素 pus...
Redis相關的一些問題
在高併發下,查詢乙個不存在的值時,快取不會被命中,導致大量請求直接落到資料庫上,如活動系統裡面查詢乙個不存在的活動。解決方案 布隆過濾器。首先也是對所有可能查詢的引數以hash形式儲存,當使用者想要查詢的時候,使用布隆過濾器發現不在集合中,就直接丟棄,不再對持久層查詢。快取空物件。當持久層不命中後,...
建立redis集群,遇到的一些問題
之前在建立redis單機的時候,已經搭建過一次redis 現在是在ceontos環境下,搭建集群 我是參考如下貼的 1 在建立集群的時候,需要安裝ruby,來管理集群 wget tar zxvf ruby 2.3.5.tar.gz cd ruby 2.3.5 configure prefix opt...