微服務(wù)實(shí)踐目錄伏恐,可以參見連接臭笆。
緩存系列包括:
1.微服務(wù)管理-11.緩存概述
1.微服務(wù)管理-11.緩存-0.技術(shù)
1.微服務(wù)管理-11.緩存-1.多級緩存設(shè)計(jì)
1.微服務(wù)管理-11.緩存-2.典型緩存架構(gòu)設(shè)計(jì)
1.微服務(wù)管理-11.緩存-3.實(shí)踐-緩存使用
1.微服務(wù)管理-11.緩存-4.總結(jié)
背景
在前面的幾篇文章中討論了很多關(guān)于緩存使用時(shí)要注意的事項(xiàng)愁铺。但在實(shí)際的工作中在哪些地方考慮這些事項(xiàng)其實(shí)還是不明確。為了幫助讀者在生產(chǎn)中更好的使用緩存孟岛,本文主要以例子的方式說明在生產(chǎn)環(huán)境中使用緩存的方式斤贰。
示例
結(jié)合前面幾篇文章中的內(nèi)容次询,并通過盡量的減少對于(相對)慢速服務(wù)/設(shè)備的訪問來提高業(yè)務(wù)處理速度屯吊。但在業(yè)務(wù)處理過程中減少對于慢速服務(wù)/設(shè)備的訪問并不一定就可以提升業(yè)務(wù)處理速度盒卸,并還有可能帶來其他的問題蔽介。所以煮寡,這里展示幾個例子來解釋這些問題,并提供可用的生產(chǎn)環(huán)境方案杈帐。
大量請求的終極方案
在前幾篇文章中出現(xiàn)過大量請求的時(shí)候的一個終極方案专钉,如下:
這個方案參照了之前使用cdn緩存業(yè)務(wù)接口的方式來設(shè)計(jì)。通過OpenResty中支持的腳本語言Lua去控制本地返回還是使用Redis中結(jié)果返回娃兽。還有如果發(fā)生miss之后還需要調(diào)用后端服務(wù)來更新緩存菇民。
這種方式的緩存的特點(diǎn):適合IO密集型業(yè)務(wù)中,不適合計(jì)算密集型業(yè)務(wù)投储。并在業(yè)務(wù)過程中查看的業(yè)務(wù)占系統(tǒng)業(yè)務(wù)的絕大部分第练。例如:大型線上商城中的商品展示,新聞網(wǎng)站玛荞,網(wǎng)站門戶娇掏,微博/陌生人社交,音視頻服務(wù)勋眯,圖片網(wǎng)站等婴梧。
緩存更新示例
在實(shí)際的緩存更新過程中一般有以下幾種方式來更新緩存:
這幾種方式針對不同的緩存模型來進(jìn)行。
-
被動更新
使用領(lǐng)域事件客蹋,定時(shí)進(jìn)行緩存的更新動作。在數(shù)據(jù)源發(fā)生變化時(shí)通過事件的方式通知各個關(guān)心這部分?jǐn)?shù)據(jù)的服務(wù)去更新自己保存的信息一般情況下在事件驅(qū)動模式下可以完成钧舌。但很多時(shí)候服務(wù)/系統(tǒng)之前的數(shù)據(jù)的同步工作不會這么順利的解決隅很,所以還可以使用定時(shí)輪詢數(shù)據(jù)源的方式檢查服務(wù)緩存數(shù)據(jù)是否和數(shù)據(jù)源數(shù)據(jù)一致。 -
主動更新
在用戶訪問的時(shí)候檢查并更新緩存仔粥。在用戶對業(yè)務(wù)進(jìn)行訪問時(shí)對緩存的數(shù)據(jù)進(jìn)行檢查和更新麦向,這樣可以保證只有用戶用才對緩存進(jìn)行操作,用戶不用這部分業(yè)務(wù)的時(shí)候就不對緩存進(jìn)行操作。這樣可以減少對于計(jì)算資源的消耗很有幫助,還可以減少緩存中空間的占用。
被動更新的特點(diǎn)在于有一個系統(tǒng)中的觸發(fā)源去觸發(fā)數(shù)據(jù)的更新動作。主動更新的特點(diǎn)在于只有用戶在使用系統(tǒng)的特定功能時(shí)才會觸發(fā)更新的動作罢荡。被動更新可以保證緩存和數(shù)據(jù)源之間的數(shù)據(jù)永遠(yuǎn)是一致的笼才,并且不需要過多的補(bǔ)償機(jī)制來保證數(shù)據(jù)一致性。主動更新的方式就會發(fā)生緩存和數(shù)據(jù)源中數(shù)據(jù)不一致的問題。所以,在后面會討論在主動更新模式下盡量保證數(shù)據(jù)一致性的方式腐芍。
定時(shí)更新的方式在很多地方都有使用冗酿,例如CDN的定時(shí)溯源的機(jī)制就是以這種方式運(yùn)行的弱判。
被動更新
事件更新
事件更新中最核心的概念是事件膀跌,這里的事件最好是在領(lǐng)域驅(qū)動設(shè)計(jì)中的事件風(fēng)暴階段中這里出來的事件丛忆。因?yàn)檫@種事件代表著業(yè)務(wù)發(fā)生的動作,也代表著業(yè)務(wù)價(jià)值的流動。
一般情況下領(lǐng)域驅(qū)動設(shè)計(jì)中的事件是從限界上下文中發(fā)送出來的由另一個限界上下文接收和處理尘惧。但在一些情況下也可以是同一個限界上下文中的不通過聚合發(fā)送和接收。
基于現(xiàn)在的系統(tǒng)架構(gòu)模式幾乎都使用微服務(wù)模式疙剑,所以最好使用消息組播的方式來處理消息管挟。這樣可以防止一個邏輯服務(wù)的不同實(shí)例都在處理同一個緩存key导帝。
定時(shí)更新
在微服務(wù)架構(gòu)模式下,任務(wù)、定時(shí)器都會由一個任務(wù)調(diào)度中心來完成挖垛。所以菇怀,在使用定時(shí)觸發(fā)緩存更新時(shí)還是使用分布式任務(wù)調(diào)度中心來完成任務(wù)的調(diào)度工作。這樣可以保證同一時(shí)間只有一個實(shí)例在處理蝶怔。以這種方式簡單的進(jìn)行排他工作,防止同時(shí)操作緩存的問題充包。
被動更新
用戶觸發(fā)更新也可以稱為非固定周期更新点额,因?yàn)橛脩舻挠|發(fā)時(shí)間是不確定的料扰、任何時(shí)候都可能。有一種隨機(jī)數(shù)的產(chǎn)生方式就是使用類似的機(jī)制:操作系統(tǒng)使用內(nèi)核接受到中斷的時(shí)間點(diǎn)作為隨機(jī)數(shù)使用亩歹。所以坝撑,用戶觸發(fā)更新的方式就是一種隨機(jī)發(fā)生的緩存更新。
下面一一說明圖中內(nèi)容的含義:
- 深藍(lán)色的矩形塊:緩存更新間隔
緩存更新間隔代表緩存最小更新周期,只有緩存在超過這個周期還沒有更新的情況下才會進(jìn)行觸發(fā)更新综液。更新間隔中多次使用緩存則不進(jìn)行更新。
緩存更新間隔的作用是防止用戶在很短的時(shí)間段內(nèi)多次使用這部分?jǐn)?shù)據(jù)喳钟,而產(chǎn)生的每次都要更新緩存的問題。如果每次都要更新緩存中的數(shù)據(jù)尉咕,那么和未使用緩存的系統(tǒng)行為就是一致的犁柜,那就相當(dāng)于沒有使用緩存稚疹。 - 綠色箭頭:觸發(fā)事件
觸發(fā)事件是系統(tǒng)接收到的請求赂鲤。在請求處理中要判斷是否超過了一個更新間隔寺谤,如果緩存的存在時(shí)間已經(jīng)超過一個更新間隔則需要對緩存進(jìn)行更新。
這里隱藏著一個點(diǎn)迫悠,在非固定周期中更新了緩存是需要重新設(shè)置緩存的過期時(shí)間的搁拙。因?yàn)檫@樣就會造成同一塊業(yè)務(wù)的緩存失效時(shí)間點(diǎn)不一致字柠。而緩存失效時(shí)間點(diǎn)就可以避免緩存雪崩的產(chǎn)生搀庶。 - 綠色雙向箭頭:過期時(shí)間
過期時(shí)間是為了保證緩存中的數(shù)據(jù)可以正常的過期被提出緩存揍庄,這樣來提高緩存的使用率馏谨。
另外在過期時(shí)間中還隱藏了一個重要的問題:緩存存在是否就可以直接返回給業(yè)務(wù)惧互?在緩存存在的情況下艾猜,更新緩存的動作是異步的執(zhí)行了算柳,讓現(xiàn)有的數(shù)據(jù)直接返回給業(yè)務(wù)。還是更新緩存的動作同步執(zhí)行熙暴,等更新完緩存之后再返回周霉。這里在下一節(jié)中詳細(xì)討論掂器。 - 公式:更新率
更新率跟下面所要討論的緩存更新方式有很重要的關(guān)聯(lián)。這里先討論一下更新率代表著什么俱箱?更新率代表著數(shù)據(jù)不一致的情況最大可接受的范圍国瓮。因?yàn)閿?shù)據(jù)源在更新間隔內(nèi)更新了數(shù)據(jù),在緩存使用服務(wù)中更新緩存的頻率狞谱。所以乃摹,在后面討論的同步和異步方式中,同步時(shí)推薦更新率月趨近于1越好芋簿,而異步方式越小越好峡懈。
因?yàn)橥椒绞礁侣授吔?,因?yàn)槿绻谟|發(fā)事件超過更新間隔時(shí)永遠(yuǎn)都會更新緩存与斤,所以這兩個值相等比較好肪康。在異步更新時(shí)為了保證緩存和數(shù)據(jù)源的一致性,保持比較小的一個更新率可以保證數(shù)據(jù)的一致性撩穿,并能保證緩存空間被充分的利用磷支。
同步、異步更新
如上圖中箭頭所指向位置食寡,在這里使用同步方式還是使用異步方式雾狈。從這兩種方式產(chǎn)生的問題角度入手分析他們的優(yōu)缺點(diǎn):
- 同步
同步的方式會造成接口響應(yīng)時(shí)間偏差較大,因?yàn)橛行┎徽{(diào)用溯源接口抵皱,有些調(diào)用善榛。這導(dǎo)致接口在不同時(shí)間的行為不一致造成接口響應(yīng)時(shí)間偏差較大。 - 異步
異步方式當(dāng)前返回的值都是緩存中的值呻畸,在特定的時(shí)間點(diǎn)上返回的數(shù)據(jù)是不一致的移盆。可能對冪等性有干擾伤为。
不管同步還是異步都有可能造成緩存擊穿問題咒循,所以更新緩存的過程中最好進(jìn)行一些排他動作以防止洪泛的發(fā)生。
總結(jié)
主動更新绞愚、被動更新這些技術(shù)適應(yīng)于不同的場景叙甸。它們各自有各自的優(yōu)缺點(diǎn),在技術(shù)設(shè)計(jì)階段需要考慮實(shí)際的業(yè)務(wù)場景來決策到底使用那種方式合適位衩。這個很多時(shí)候是需要設(shè)計(jì)人員的經(jīng)驗(yàn)來進(jìn)行決策裆蒸。所以,任何一種軟件設(shè)計(jì)過程都是一個決策和權(quán)衡的過程糖驴。
使用緩存的目標(biāo)就是:通過減少對慢速服務(wù)的訪問光戈,來提速哪痰。所以在實(shí)際的緩存環(huán)境中遂赠,最主要的目標(biāo)是減少訪問慢速來達(dá)到使用緩存提速的目標(biāo)久妆。而在這個過程中可以使用的整體方案很多,可以通過不同事項(xiàng)的調(diào)整來完成自己的方案跷睦。