Redis相關的一些問題

1. 緩存穿透

在高併發下,查詢一個不存在的值時,緩存不會被命中,導致大量請求直接落到數據庫上,如活動系統裏面查詢一個不存在的活動。

解決方案:

  1. 布隆過濾器。首先也是對所有可能查詢的參數以hash形式存儲,當用戶想要查詢的時候,使用布隆過濾器發現不在集合中,就直接丟棄,不再對持久層查詢。
  2. 緩存空對象。當持久層不命中後,即使返回的空對象也將其緩存起來,同時會設置一個過期時間,之後再訪問這個數據將會從緩存中獲取,保護了後端數據源。缺點是:佔用更多的內存。

2. 緩存雪崩

在高併發下,大量的緩存key在同一時間失效,導致大量的請求落到數據庫上,如活動系統裏面同時進行着非常多的活動,但是在某個時間點所有的活動緩存全部過期。

解決方案:

  1. 給緩存的失效時間,加上一個隨機值,避免集體失效。
  2. 雙緩存。我們有兩個緩存,緩存A和緩存B。緩存A的失效時間爲20分鐘,緩存B不設失效時間。自己做緩存預熱操作。然後細分以下幾個小點
    ● I 先從緩存A讀數據,有則直接返回;
    ● II A沒有數據,直接從B讀數據,直接返回,並且異步啓動一個更新線程;
    ● III 更新線程同時更新緩存A和緩存B。

3. 緩存擊穿

一個key非常熱點,在不停的扛着高併發,高併發集中對這一個點進行訪問,當這個key在失效的瞬間,持續的高併發就穿破緩存,直接請求數據庫,就像在一個屏障上鑿開了一個洞。

解決方案:

  1. 使用互斥鎖(mutex key):同一時刻只有一個client能夠獲取數據。
  2. 永不過期:沒有設置過期時間就保證不會出現熱點key過期問題

4. 緩存併發競爭(併發set)

多個client線程同時set key引起的併發問題

解決方案:

  1. 分佈式鎖+時間戳:準備一個分佈式鎖(Redis自己有實現),併發訪問哪個資源,就將該資源作爲key,值爲一個唯一的隨機值(如unix時間戳加上ip之類的),這個key在Redis中存在,表示對此資源上鎖了,用完再把這個key刪了就行。
  2. 消息隊列:把Redis.set操作放在隊列中使其串行化,必須的一個一個執行。這種方式在一些高併發的場景中算是一種通用的解決方案。

5. 如果master還未將AOF同步給slave就掛了,此時failover將此slave提升爲新的master,那麼如何保證最終一致性?

保證不了,就是丟了。

[1] redis緩存與數據一致性

[2] 緩存穿透、緩存擊穿和緩存雪崩實踐

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章