redis緩存設計

緩存的利於弊及應用場景

這裏咱們主要討論以Redis爲表明的基於內存的緩存方案。redis

緩存的優勢

  • 提高訪問速度,減小後端如數據庫存儲的時間消耗
  • 減輕後端如數據庫的壓力

緩存帶來的問題

任何系統每增長一個組件,在帶來新的特性的同時也必然會帶來額外的複雜度,能夠說系統的設計過程就是一個折中的過程。緩存的引入也帶來了一些須要考慮的問題:算法

  • 數據不一致: 緩存層和存儲層的數據存在着必定的時間窗口的不一致性,時間窗口跟緩存更新策略有關
  • 代碼維護成本: 須要同時處理緩存和存儲層的邏輯
  • 運維成本: 爲了保證redis的可用性和併發性,會引入redis sentinelredis cluster等架構,這又增長了系統複雜性和運維難度。

應用場景

  • 開銷大的複雜運算
  • 加速請求響應

緩存更新策略

  • LRU/LFU/FIFO算法
  • 超時剔除
  • 主動更新

應用

  • 低一致性業務建議:最大內存+淘汰策略
  • 高一致性:超時剔除和主動更新

緩存穿透

緩存穿透: 是指查詢一個根本不存在的數據, 緩存層和存儲層都不會命中。這會形成存儲層壓力變大。數據庫

緩存穿透的發現:

一般能夠在程序中分別統計後端

  • 總調用數
  • 緩存層命中數
  • 存儲層命中數

若是發現大量存儲層空命中, 可能就是出現了緩存穿透問題。緩存

緩存穿透的解決方案

  • 緩存空對象
    • 佔用內存: 緣由是爲了防止大量空對象(被攻擊) 方案是能夠設置比較短的過時時間,讓其自動剔除
    • 數據不一致: 緣由是存儲層添加了數據,可是緩存空對象還沒過時, 方案是可使用消息隊列,
  • bloomfilter攔截
    • 這種方法適用於數據命中不高、 數據相對固定、 實時性低(一般是數據集較大) 的應用場景, 代碼維護較爲複雜,可是緩存空間佔用少。

無底洞優化

因爲緩存集羣一般會將key進行hash,而後映射到相應的節點上,形成key的分佈與業務無關,批量操做一般須要從不一樣節點上獲取,相比於單機批量操做只涉及一次網絡操做,分佈式批量操做會涉及屢次網絡時間。網絡

常見的IO優化思路:架構

  • 命令自己的優化,例如優化SQL語句等
  • 減小網絡通訊次數
    • pipeline
    • mget
  • 下降介入成本,例如客戶端使用長連/鏈接池、NIO等

集羣客戶端優化方案併發

  • 串行IO,把key的請求按照節點分組,而後依次處理
  • 並行IO,把key的請求按照節點分組,而後並行處理
  • hash_tag實現, 能夠將多個key強制分配到一個節點上,它的操做時間=1此網絡時間+n次命令時間,性能最高,可是數據維護成本高,數據易傾斜

雪崩優化

雪崩定義:因爲緩存層承載着大量請求,有效地保存了存儲層,可是若是緩存層因爲某些緣由不能提供服務,因而全部的請求都會到達存儲層,存儲層的調用會暴增。運維

說到底就是緩存扛不住了,把壓力衝擊到了存儲層。分佈式

預防和緩解緩存雪崩問題的三個方面

  • 保證緩存層服務高可用性,redis提供了Redis SentinelRedis Cluster
  • 依賴隔離組件爲後端限流並降級,降級機制,如Hystrix
  • 提早演練,項目上線前,演練緩存層宕掉後,應用及後端的負載狀況以及可能出現的問題。

熱點key重建優化

緩存+過時時間的策略既能夠加速數據讀寫,又保證數據的按期更新,這種模式基本可以知足絕大部分需求。但有兩個問題:

  • 熱點key,併發量很是大
  • 重建緩存不能在短期完成(長時生成緩存)

熱點key重建

  • 互斥鎖
  • 永遠不過時,可是重建期間會有不一致問題
相關文章
相關標籤/搜索