緩存的利於弊及應用場景
這裏咱們主要討論以Redis爲表明的基於內存的緩存方案。redis
緩存的優勢
- 提高訪問速度,減小後端如數據庫存儲的時間消耗
- 減輕後端如數據庫的壓力
緩存帶來的問題
任何系統每增長一個組件,在帶來新的特性的同時也必然會帶來額外的複雜度,能夠說系統的設計過程就是一個折中的過程。緩存的引入也帶來了一些須要考慮的問題:算法
- 數據不一致: 緩存層和存儲層的數據存在着必定的時間窗口的不一致性,時間窗口跟緩存更新策略有關
- 代碼維護成本: 須要同時處理緩存和存儲層的邏輯
- 運維成本: 爲了保證redis的可用性和併發性,會引入
redis sentinel
或redis cluster
等架構,這又增長了系統複雜性和運維難度。
應用場景
緩存更新策略
應用
- 低一致性業務建議:最大內存+淘汰策略
- 高一致性:超時剔除和主動更新
緩存穿透
緩存穿透: 是指查詢一個根本不存在的數據, 緩存層和存儲層都不會命中。這會形成存儲層壓力變大。數據庫
緩存穿透的發現:
一般能夠在程序中分別統計後端
若是發現大量存儲層空命中, 可能就是出現了緩存穿透問題。緩存
緩存穿透的解決方案
- 緩存空對象
- 佔用內存: 緣由是爲了防止大量空對象(被攻擊) 方案是能夠設置比較短的過時時間,讓其自動剔除
- 數據不一致: 緣由是存儲層添加了數據,可是緩存空對象還沒過時, 方案是可使用消息隊列,
- bloomfilter攔截
- 這種方法適用於數據命中不高、 數據相對固定、 實時性低(一般是數據集較大) 的應用場景, 代碼維護較爲複雜,可是緩存空間佔用少。
無底洞優化
因爲緩存集羣一般會將key進行hash,而後映射到相應的節點上,形成key的分佈與業務無關,批量操做一般須要從不一樣節點上獲取,相比於單機批量操做只涉及一次網絡操做,分佈式批量操做會涉及屢次網絡時間。網絡
常見的IO優化思路:架構
- 命令自己的優化,例如優化SQL語句等
- 減小網絡通訊次數
- 下降介入成本,例如客戶端使用長連/鏈接池、NIO等
集羣客戶端優化方案併發
- 串行IO,把key的請求按照節點分組,而後依次處理
- 並行IO,把key的請求按照節點分組,而後並行處理
- hash_tag實現, 能夠將多個key強制分配到一個節點上,它的操做時間=1此網絡時間+n次命令時間,性能最高,可是數據維護成本高,數據易傾斜
雪崩優化
雪崩定義:因爲緩存層承載着大量請求,有效地保存了存儲層,可是若是緩存層因爲某些緣由不能提供服務,因而全部的請求都會到達存儲層,存儲層的調用會暴增。運維
說到底就是緩存扛不住了,把壓力衝擊到了存儲層。分佈式
預防和緩解緩存雪崩問題的三個方面
- 保證緩存層服務高可用性,redis提供了
Redis Sentinel
和Redis Cluster
- 依賴隔離組件爲後端限流並降級,降級機制,如
Hystrix
- 提早演練,項目上線前,演練緩存層宕掉後,應用及後端的負載狀況以及可能出現的問題。
熱點key重建優化
緩存+過時時間的策略既能夠加速數據讀寫,又保證數據的按期更新,這種模式基本可以知足絕大部分需求。但有兩個問題:
- 熱點key,併發量很是大
- 重建緩存不能在短期完成(長時生成緩存)
熱點key重建