現在,緩存系統的應用很是普遍,可以用來提升併發數、數據吞吐量,提升快速響應能力。那麼當數據量達到必定程度,單機環境可能就顯得有些力不從心了,就須要一個分佈式緩存系統。html
如上圖所示,首先緩存大體能夠分爲四大類。node
本文主要探討各分佈式緩存系統,如圖 1-1 所示,列出了五種:面試
其中 EvCache 和 Aerospike 使用場景不是那麼通用和普遍。redis
除此以外,還有三種常見緩存系統。spring
Tair:阿里開源,跨機房、性能隨結點添加線性上升、適用大數據量。Tair 還有三種引擎。shell
Memcache: 不支持數據同步、分佈式支持較差。數據庫
Redis: 社區活躍、使用最多。設計模式
綜上所述,在通常狀況下,考慮到適用性和穩定性,Redis 是搭建緩存系統的最優選擇。如下將基於 Redis 介紹。緩存
如頂部圖 1-1 所示,列出了 Redis 的集羣高可用的方案,基本能夠分爲三種。服務器
常見的集羣架構,搭建簡單,主要實現讀寫分離和備份,能夠由 Master 負責讀寫,Slave 負責備份。但存在故障恢復複雜、水平拓展難、寫能力受限等問題。結構圖以下:
Redis Sentinel 是社區版本推出的原生高可用解決方案。由一或多個哨兵實例監視任意個主從服務器,且在 Master 宕機時,自動將宕機服務器屬下的 Slave 服務器升級爲 主服務器,從而保證系統的可用性。較主從實現的監控、選主。但問題主要是要保證 Master 的 HA 切換。結構圖以下:
到這裏以上兩種機制其實只能算做「集羣」,並不是嚴格意義上的「分佈式」。接着來看看分佈式方案。
集羣強調高可用,分佈式在集羣的基礎上又強調協做。
任何分佈式存儲系統,首先面臨的就是 sharding(分片)問題,如頂部圖 1-1 所示該問題有爲三種解決方法。
顧名思義,將數據分片的路由功能交給客戶端,但這是一種靜態分片,維護性差。基本是不予考慮的。
經過代理分發到具體的 redis 實例。有兩個經常使用解決方案。
其實,這兩種代理分片的方案,都是在 Redis 官方未推出良好的分佈式方案時的產生的,在官方更新提供更優策略後都再也不維護。
這就要談到 Redis 官方方案 Redis-cluster 。
在 Redis 3.0 以前是沒有較好的分佈式方案的,這也是第三方方案出現的緣由。3.0 開始,官方推出了去中心化的分佈式方案。集羣中包含 16384 個散列槽,每一個節點負責其中一部分。
先看下拓撲圖:
每一個節點打開兩個 TCP 鏈接,一個負責給客戶端提供服務,一個負責節點間通訊。
此刻要說說 CAP 了 :Consistency(一致性)、Availability(可用性)、Partition tolerance(分區容錯性) 。對分佈式系統而言,CAP 必須犧牲一者。Redis Cluster 的設計目標主要是高性能、高可用和高擴展,只好拋棄一部分數據一致性。
數據一致性:因爲Redis Cluster 使用異步複製, 在某些狀況下如 Master 宕機但未同步至 Slave,可能會致使丟失寫入。在絕對須要支持同步寫入時,可經過 WAIT 命令實現,可以使得丟失寫入的可能性大大下降。
可用性:當集羣中一部分節點故障後,集羣總體能響應客戶端讀寫請求。
高性能和拓展:操做某個 key 時,不會先找到節點再處理,而是直接直接重定向到該節點,同時相較代理分片也少了 proxy 的鏈接損耗。
以上介紹了簡單介紹了常見緩存系統,並具體列出了基於 Redis 的集羣方案。下面談一談緩存系統常見的問題。
以下圖所示,列出七個常見問題。
指訪問不存在的數據,從而繞過緩存,直接請求到了數據源,當請求過多,就會對 DB 形成壓力。
緩存擊穿實際是緩存雪崩的一個特例。指當某些熱點 key 過時時,就會有大量的請求擊穿到 DB。
互斥鎖:在緩存失效的時候,不當即 load db,能夠先用如 SETNX 等命令去 set 一個 mutex key,當操做返回成功時,說明拿到鎖,此刻該線程進行 load db 的操做並更新緩存;不然未拿到鎖就(可休眠一段)重試 get 緩存的方法。但要注意死鎖風險。
不過時
同一時刻大量緩存失效(故障), 請求到了 DB。
若是保證數據一致性。列出四種更新策略:
Cache Aside :最經常使用的。失效時回源取數據,更新;命中時,返回緩存數據;更新時先數據源更新,再更新緩存。
Write Back :更新數據時,只更新緩存,不更新數據源。緩存異步批量更新數據庫。
Read/Write Through
對於熱點數據的處理方法。
指能夠將某些的緩存數據提早加載到緩存系統,提早避免在如熱點數據大量請求到庫。
指當訪問量劇增、服務出現問題或非核心服務影響到核心流程的性能時,仍需保證主服務可用。可根據一些關鍵數據自動降級,也可配置開關人工降級。
對於 Redis Cluster 環境的搭建和基礎使用很是簡單。
不管基於何種方式,只要搭建好 n 臺 redis 服務並保證各服務間能夠互相通信後,任意進入一個 redis 服務鍵入:
redis-cli --cluster create IP1:port1 IP2:port2 IP3:port3 IP4:port4 IP5:port5 IP6:port6 ... --cluster-replicas 1
便可。以後可使用 cluster node 和 cluster info 命令查看集羣、節點信息。
而對於廣大 JAVA 開發,Spring Data Redis 從 1.7 起即支持 Redis Cluster,只需配置 Master 節點地址(和密碼)。
spring.redis.cluster.nodes=ip1:port1,ip2:port2,ip3:port3
加入依賴
compile("org.springframework.boot:spring-boot-starter-data-redis")
便可經過 RedisTemplate 使用。
本文從緩存系統的選擇出發,基於 Redis 介紹了幾種集羣方案並重點說明了 Redis Cluster 方案。以後列出緩存系統常見問題及常看法決方案,最後對使用作了簡單說明。
固然,如何去落地,如何解決這些問題還須要根據實際場景具體分析和處理。
原文連接:https://mp.weixin.qq.com/s/cONKlGQze1WzyC2yzbZ0RA 歡迎關注公衆號 【碼農開花】一塊兒學習成長 我會一直分享Java乾貨,也會分享免費的學習資料課程和麪試寶典 回覆:【計算機】【設計模式】【面試】有驚喜哦