1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        分布式緩存的選擇

        共 4292字,需瀏覽 9分鐘

         ·

        2020-12-17 17:56

        分布式緩存的選擇和問題

        如今,緩存系統(tǒng)的應(yīng)用非常廣泛,能夠用來提高并發(fā)數(shù)、數(shù)據(jù)吞吐量,提高快速響應(yīng)能力。那么當(dāng)數(shù)據(jù)量達(dá)到一定程序,單機(jī)環(huán)境可能就顯得有些力不從心了,就需要一個(gè)分布式緩存系統(tǒng)。

        1. 緩存系統(tǒng)的選擇

        圖1-1

        如上圖所示,首先緩存大致可以分為四大類。

        • CDN緩存:CDN即內(nèi)容分發(fā)網(wǎng)絡(luò),CDN邊緣節(jié)點(diǎn)將數(shù)據(jù)緩存起來。
        • 反向代理緩存:如Nginx的緩存。
        • 本地緩存:代表的有EhCache和Guava Cache
        • 分布式緩存:各緩存系統(tǒng)

        本文主要探討各分布式緩存系統(tǒng),如下圖所示,列出了五種:

        之后對MemCache、Tair、Redis做出對比

        其中EvCacheAerospike使用場景不是那么通用和廣泛。

        • EvCache:是Netflix的基于memcached & spymemcached的緩存方案。
        • Aerospike:是可基于SSD的K-V NoSQL數(shù)據(jù)庫。

        除此之外,還有三種常見緩存系統(tǒng)。

        • Tair:阿里開源,跨機(jī)房、性能隨結(jié)點(diǎn)添加線性上升、適用大數(shù)據(jù)量。Tair還有三種引擎
          • LDB: 基于google levelDB,支持kv和類hashmap結(jié)構(gòu),性能稍低,持久化可靠性最高。
          • MDB: 基于memcache,支持kv和類hashMap,性能最優(yōu),不支持持久化存儲。
          • RDB: 基于Redis.
        • Memcache: 不支持?jǐn)?shù)據(jù)同步、分布式支持較差。
        • Redis: 社區(qū)活躍、使用最多。

        綜上所述,在一般情況下,考慮到適用性和穩(wěn)定性,Redis 是搭建緩存系統(tǒng)的最優(yōu)選擇。以下將基于 Redis 介紹。

        2. Redis集群緩存方案

        如頂部圖所示,列出了Redis的集群高可用的方案,基本可以分為三種。

        主從機(jī)制

        常見的集群的架構(gòu),搭建簡單,主要實(shí)現(xiàn)讀寫分離和備份,可以由 Master 負(fù)責(zé)讀寫,Slave 負(fù)責(zé)備份。但存在故障恢復(fù)復(fù)雜、水平拓展難、寫能力受限等問題。結(jié)構(gòu)圖如下:

        哨兵機(jī)制

        Redis Sentinel 是社區(qū)版本推出的原生高可用解決方案。由一或多個(gè)哨兵實(shí)例監(jiān)視任意個(gè)主從服務(wù)器,且在 Master 宕機(jī)時(shí),自動(dòng)將宕機(jī)服務(wù)器屬下的 Slave 服務(wù)器升級為 主服務(wù)器,從而保證系統(tǒng)的可用性。較主從實(shí)現(xiàn)的監(jiān)控、選主。但問題主要是要保證Master的HA切換。結(jié)構(gòu)圖如下:

        “分布式”

        到這里其實(shí)以上兩種機(jī)制其實(shí)只能算作“集群”,并非嚴(yán)格意義上的“分布式”。接著來看看分布式方案。

        集群強(qiáng)調(diào)高可用,分布式又強(qiáng)調(diào)協(xié)作。

        3. Redis分布式緩存方案

        任何分布式存儲系統(tǒng),首先面臨的就是 sharding(分片)問題,如頂部圖1-1所示可分為三種方式。

        客戶端分片

        顧名思義,將數(shù)據(jù)分片的路由功能交給客戶端,但這是一種靜態(tài)分片,維護(hù)性差?;径允遣挥杩紤]的。

        代理分片

        通過代理分發(fā)到具體的redis實(shí)例。有兩個(gè)常用解決方案。- Twemproxy Twitter開源,輕量級,但不再維護(hù),也無法平滑地?cái)U(kuò)容/縮容,運(yùn)維也不是很友好,性能一般。- Codis 豌豆莢開源,支持水平拓展,運(yùn)維平臺完善,性能較 Twemproxy 快。Codis在國內(nèi)使用較多,同時(shí)代理分片的思路也有很多公司在此基礎(chǔ)開發(fā)了自己的二次方案。不過Codis也不再維護(hù)。

        其實(shí),這兩種代理分片的方案,都是在 Redis 官方未推出良好的分布式方案時(shí)的策略,在官方更新后都不再維護(hù)。

        服務(wù)器端分片

        這就要談到 Redis 官方的方案 Redis-cluster 。

        在 Redis3.0 之前是沒有較好的分布式方案的,這也是第三方方案出現(xiàn)的原因。3.0 開始,官方推出了去中心化的分布式方案。集群中包含16384個(gè)散列槽,每個(gè)節(jié)點(diǎn)負(fù)責(zé)其中一部分。

        先看下拓?fù)鋱D:

        每個(gè)節(jié)點(diǎn)打開兩個(gè)TCP連接,一個(gè)負(fù)責(zé)給客戶端提供服務(wù),一個(gè)負(fù)責(zé)節(jié)點(diǎn)間通信。

        此刻要說說 CAP了 :Consistency(一致性)、Availability(可用性)、Partition tolerance(分區(qū)容錯(cuò)性) 。對分布式系統(tǒng)而言,CAP 必須犧牲一者。Redis Cluster 的設(shè)計(jì)目標(biāo)主要是高性能、高可用和高擴(kuò)展, 只好拋棄一部分?jǐn)?shù)據(jù)一致性.

        • 數(shù)據(jù)一致性:由于Redis Cluster 使用異步復(fù)制, 在某些情況下如Master宕機(jī)但未同步至Slave, 可能會丟失寫入。在絕對需要時(shí)支持同步寫入的時(shí)候, 可通過 WAIT 命令實(shí)現(xiàn), 可使得丟失寫入的可能性大大降低。
        • 可用性:當(dāng)集群中一部分節(jié)點(diǎn)故障后, 集群整體能響應(yīng)客戶端讀寫請求。
          • 節(jié)點(diǎn)間定時(shí)互 ping , 當(dāng)超過一半Master 判定某節(jié)點(diǎn)失敗,則標(biāo)為 FAIL, 會向集群廣播節(jié)點(diǎn)下線的消息。如下線節(jié)點(diǎn)是帶有槽的主節(jié)點(diǎn),則要從它的從節(jié)點(diǎn)選出一個(gè)替換。
        • 高性能和拓展:操作某個(gè) key時(shí),不會先找到節(jié)點(diǎn)再處理,而是直接直接重定向到該節(jié)點(diǎn), 同時(shí)相較代理分片也少了 proxy 的連接損耗。
          • 但是在進(jìn)行multiple key操作時(shí)需要keys位于同一個(gè)slot上,需要使用hash tags,使用{}強(qiáng)制將某些key映射到每個(gè)slot,以便進(jìn)行multiple?。
          • 在拓展方面,Redis Cluster 最大支持線性拓展1000個(gè)節(jié)點(diǎn),將新節(jié)點(diǎn)加入集群后可以通過命令指定和平均的從已有節(jié)點(diǎn)分配slot。

        3. 緩存常見問題

        以上介紹了簡單介紹了常見緩存系統(tǒng),并具體列出了基于Redis的集群方案。下面談一談緩存系統(tǒng)常見的問題。

        如下圖所示,列出七個(gè)常見問題。

        3.1. 緩存穿透

        指訪問不存在的數(shù)據(jù),從而繞過緩存,直接請求到了數(shù)據(jù)源,當(dāng)請求過多,就會對 DB 造成壓力。

        • 空 key:指對于不存在的數(shù)據(jù)也將 key 存空值入緩存系統(tǒng),這樣下次訪問也會得到返回。但只適用于空數(shù)據(jù)key有限、key 重復(fù)請求概率高,如果量大且不重復(fù),就會造成很多無用 key 的創(chuàng)建。
        • 布隆過濾器:布隆過濾器是一個(gè)很長的二進(jìn)制向量和一系列隨機(jī)映射函數(shù)。可用于檢索一個(gè)元素是否在一個(gè)集合中加一層對空值的過濾器,空間和時(shí)間效率都很高。但由于 hash 產(chǎn)生的碰撞可能存在誤判,以及因不存儲 key 導(dǎo)致的無法刪除。適用于空數(shù)據(jù)key各不同、重復(fù)請求概率低。

        3.2. 緩存擊穿

        緩存擊穿實(shí)際是緩存雪崩的一個(gè)特例。指當(dāng)某些熱點(diǎn)key過期時(shí),就會有大量的請求擊穿到DB。

        • 互斥鎖 在緩存失效的時(shí)候,不立即load db,可以先用如SETNX等命令去set一個(gè)mutex key,當(dāng)操作返回成功時(shí),說明拿到鎖,此刻該線程進(jìn)行l(wèi)oad db的操作并更新緩存;否則未拿到鎖就(可休眠一段)重試 get 緩存的方法。但要注意死鎖風(fēng)險(xiǎn)。
        • 不過期
          • 這里的不過期有兩個(gè)概念,一個(gè)指未設(shè)過期時(shí)間,那是真的不過期,那沒事了~~
          • 另一個(gè)是指通過業(yè)務(wù)邏輯,將 key 的過期時(shí)間進(jìn)行存儲,請求是判斷是否小于值,是則后臺異步更新。

        3.3. 緩存雪崩

        同一時(shí)刻大量緩存失效(故障), 請求到了DB。

        • 隨機(jī)時(shí)間:在設(shè)置過期時(shí)間時(shí),可以在基礎(chǔ)時(shí)間上 + 一個(gè)隨機(jī)的時(shí)間,等于實(shí)現(xiàn)了分批過期。
        • 后臺更新:將更新失效的工作交給后臺定時(shí)線程。
        • 限流+本地緩存:如?ehcache本地緩存 + Hystrix限流
        • 雙緩存:類似于設(shè)置主從緩存,從key不過期。

        3.4. 緩存更新與一致性

        如果保證數(shù)據(jù)一致性。列出四種更新策略:

        • Cache Aside:最常用的。失效時(shí)回源取數(shù)據(jù),更新;命中時(shí),返回緩存數(shù)據(jù);更新時(shí)先數(shù)據(jù)源更新,再跟你更新緩存。
        • Write Back:更新數(shù)據(jù)時(shí),只更新緩存,不更新數(shù)據(jù)源。緩存異步批量更新數(shù)據(jù)庫
        • Read/Write Through
          • Write Through :當(dāng)有數(shù)據(jù)更新時(shí),如未命中緩存,直接更新數(shù)據(jù)庫,并返回。如命中緩存,則更新緩存,再由 Cache 自己更新數(shù)據(jù)庫。
          • Read Through :更新數(shù)據(jù)源由緩存系統(tǒng)操作,讀取數(shù)據(jù)時(shí)如緩存失效,則取回源數(shù)據(jù)更新緩存。

        3.5. 熱點(diǎn)數(shù)據(jù)

        對于熱點(diǎn)數(shù)據(jù)的處理方法。

        • 拆分復(fù)雜結(jié)構(gòu):如二級數(shù)據(jù)結(jié)構(gòu),進(jìn)行拆分,這樣熱點(diǎn)key就被拆為若干個(gè)的 key 分布到不同節(jié)點(diǎn)。
        • 遷移熱點(diǎn):對于Redis Cluster 而言可以將熱點(diǎn) key 所在的 slot 單獨(dú)遷移到一個(gè)節(jié)點(diǎn),降低其他節(jié)點(diǎn)壓力。
        • 多副本:復(fù)制多份緩存副本,將請求分散到多個(gè)節(jié)點(diǎn)上,減輕單臺緩存服務(wù)器壓力,適合多讀少寫。

        3.6. 緩存預(yù)熱

        指可以將某些的緩存數(shù)據(jù)提前加載到緩存系統(tǒng)。提前避免在如熱點(diǎn)數(shù)據(jù)大量請求到庫。

        3.7. 緩存降級

        指當(dāng)訪問量劇增、服務(wù)出現(xiàn)問題或非核心服務(wù)影響到核心流程的性能時(shí),仍需保證主服務(wù)可用??筛鶕?jù)一些關(guān)鍵數(shù)據(jù)自動(dòng)降級,也可配置開關(guān)人工降級。

        4. Redis Cluster使用

        對于Redis Cluster環(huán)境的搭建和基礎(chǔ)使用非常簡單。

        無論基于何種方式,只要搭建好n臺 redis 服務(wù)并保證各服務(wù)間可以互相通訊后,任意進(jìn)入一個(gè)redis 服務(wù)鍵入:

        redis-cli?--cluster?create?IP1:port1?IP2:port2?IP3:port3?IP4:port4?IP5:port5?IP6:port6?...?--cluster-replicas?1

        即可。之后可以使用?cluster node?和cluster info查看集群、節(jié)點(diǎn)信息。

        而對于廣大 JAVA 服務(wù)器端開發(fā),Spring Data Redis 從1.7起即支持Redis Cluster,只需配置Master節(jié)點(diǎn)地址(和密碼)。

        spring.redis.cluster.nodes=ip1:port1,ip2:port2,ip3:port3

        加入依賴

        ?compile("org.springframework.boot:spring-boot-starter-data-redis")

        即可通過?RedisTemplate?使用。

        5. 總結(jié)

        本文從緩存系統(tǒng)的選擇出發(fā),基于 Redis 介紹了幾種集群方案并重點(diǎn)說明了 Redis Cluster 方案。之后列出緩存系統(tǒng)常見問題及常見解決方案,最后對使用做了簡單說明。

        當(dāng)然,如何去落地,如何解決這些問題還需要根據(jù)實(shí)際場景具體分析和處理。


        版權(quán)申明:內(nèi)容來源網(wǎng)絡(luò),版權(quán)歸原創(chuàng)者所有。除非無法確認(rèn),我們都會標(biāo)明作者及出處,如有侵權(quán)煩請告知,我們會立即刪除并表示歉意。謝謝!





        感謝閱讀



        瀏覽 45
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            宝贝乖~张开腿我轻点 | 男人色天堂网 | 日本特黄特色大片免费视频老年人 | 中文字幕日韩人妻在线视频 | 久久夜色精品国产噜噜v6 | 国产精品福利视频在线观看 | 91九色蝌蚪在线 | 超碰偷拍 | 欧美性猛交 | 日韩人妻一区二区三区不卡 |