在高併發下,查詢乙個不存在的值時,快取不會被命中,導致大量請求直接落到資料庫上,如活動系統裡面查詢乙個不存在的活動。
解決方案:
布隆過濾器
。首先也是對所有可能查詢的引數以hash形式儲存,當使用者想要查詢的時候,使用布隆過濾器發現不在集合中,就直接丟棄,不再對持久層查詢。
快取空物件
。當持久層不命中後,即使返回的空物件也將其快取起來,同時會設定乙個過期時間,之後再訪問這個資料將會從快取中獲取,保護了後端資料來源。缺點是:占用更多的記憶體。
在高併發下,大量的快取key在同一時間失效,導致大量的請求落到資料庫上,如活動系統裡面同時進行著非常多的活動,但是在某個時間點所有的活動快取全部過期。
解決方案:
給快取的失效時間,加上乙個隨機值,避免集體失效。
兩級快取。我們有兩個快取,快取a和快取b。快取a的失效時間為20分鐘,快取b不設失效時間。自己做快取預熱操作。然後細分以下幾個小點
● i 先從快取a讀資料,有則直接返回;
● ii a沒有資料,直接從b讀資料,直接返回,並且非同步啟動乙個更新執行緒;
● iii 更新執行緒同時更新快取a和快取b。
乙個key非常熱點,在不停的扛著高併發,高併發集中對這乙個點進行訪問,當這個key在失效的瞬間,持續的高併發就穿破快取,直接請求資料庫,就像在乙個屏障上鑿開了乙個洞。
解決方案:
使用互斥鎖(mutex key):同一時刻只有乙個client能夠獲取資料。
永不過期:沒有設定過期時間就保證不會出現熱點key過期問題
多個client執行緒同時set key引起的併發問題
解決方案:
分布式鎖+時間戳:準備乙個分布式鎖(redis自己有實現),併發訪問哪個資源,就將該資源作為key,值為乙個唯一的隨機值(如unix時間戳加上ip之類的),這個key在redis中存在,表示對此資源上鎖了,用完再把這個key刪了就行。
訊息佇列:把redis.set操作放在佇列中使其序列化,必須的乙個乙個執行。這種方式在一些高併發的場景中算是一種通用的解決方案。
保證不了,就是丟了。
[1] redis快取與資料一致性
[2] 快取穿透、快取擊穿和快取雪崩實踐
redis的一些問題
一 redis的併發競爭問題如何解決?redis為單程序單執行緒模式,採用佇列模式將併發訪問變為序列訪問。redis本身沒有鎖的概念,redis對於多個客戶端連線並不存在競爭,但是在jedis客戶端對redis進行併發訪問時會發生連線超時 資料轉換錯誤 阻塞 客戶端關閉連線等問題,這些問題均是由於客...
redis佇列一些問題
將所有指定的值插入到存於 key 的列表的頭部。如果 key 不存在,那麼在進行 push 操作前會建立乙個空列表。如果 key 對應的值不是乙個 list 的話,那麼會返回乙個錯誤。php 示例 public function push k,value else 可以使用乙個命令把多個元素 pus...
phpstudy相關的一些問題
phpstudy相關 phpstudy for linux lnmp lamp一鍵安裝包 如何切換php版本 假如你先安裝的apache php5.3 想切換成nginx php5.4 你就再走一次.phpstudy.bin 但是你會發現有一行是否安裝mysql提示選不安裝 這樣只需要編譯nginx...