微服務(wù)實踐01--微服務(wù)管理11--緩存03--典型緩存架構(gòu)設(shè)計

微服務(wù)實踐目錄,可以參見連接。

緩存系列包括:
1.微服務(wù)管理-11.緩存概述
1.微服務(wù)管理-11.緩存-0.技術(shù)
1.微服務(wù)管理-11.緩存-1.多級緩存設(shè)計
1.微服務(wù)管理-11.緩存-2.典型緩存架構(gòu)設(shè)計
1.微服務(wù)管理-11.緩存-3.實踐
1.微服務(wù)管理-11.緩存-4.總結(jié)

背景

前面介紹了緩存的設(shè)計方法,緩存技術(shù),緩存方法等內(nèi)容。本著本系列文章的一貫宗旨:理論結(jié)合實踐,所以需要將理論知識真正的落地到實踐中。本文主要說明在緩存實踐中會遇到的問題以及這些問題的解決辦法。

典型緩存架構(gòu)(緩存設(shè)計模式)

對于緩存來說數(shù)據(jù)應(yīng)該被怎樣初始化、更新、失效、持久化都是問題,對于解決這些問題有前人總結(jié)出的架構(gòu)模式幫我們解決。

  • 緩存設(shè)計模式

緩存設(shè)計模式中分為兩類:Cache-Aside、Cache-As-SoR兩類。這兩類代表著對緩存使用方式的不同的認知。Cache-Aside代表緩存就是進行快速訪問數(shù)據(jù)的過程。Cache-As-SoR代表緩存是一個數(shù)據(jù)存儲系統(tǒng),以數(shù)據(jù)存儲系統(tǒng)的使用方式使用緩存技術(shù)。

Cache-Aside即業(yè)務(wù)代碼圍繞著Cache寫,是由業(yè)務(wù)代碼維護緩存。業(yè)務(wù)代碼進行緩存的讀寫工作,讀時使用擊穿讀,寫使用雙寫方式完成。
Cache-As-SoR即把Cache看作為SoR,所有操作都是對Cache進行,然后Cache再委托給SoR進行真實的讀/寫。即業(yè)務(wù)代碼中只看到Cache的操作,看不到關(guān)于SoR相關(guān)的代碼。有是那種實現(xiàn):Read Through, Write Through, Write Behind Caching。

在緩存系統(tǒng)內(nèi)中有三個概念:

  • SoR(system-of-recode):記錄系統(tǒng),或者叫數(shù)據(jù)源,即實際存儲原始數(shù)據(jù)的系統(tǒng)
  • Cache:緩存,是SoR的快照數(shù)據(jù),Cache的訪問速度比SoR要快,放入Cache的目的是提升訪問速度,減少回溯的次數(shù)。
  • 回溯:即回到數(shù)據(jù)源頭獲取數(shù)據(jù),Cache沒命中時需要從SoR讀取數(shù)據(jù)。

Cache-As-SoR的三種實現(xiàn)方式:

  • Read Through, 業(yè)務(wù)代碼首先調(diào)用Cache,如果Cache不明中有Cache回溯到SoR,而不是業(yè)務(wù)代碼(即由Cache讀SoR)。Read Through的特點是業(yè)務(wù)代碼與更新緩存代碼分離,不像Cache-Aside模式那樣更新緩存代碼和SoR代碼角質(zhì)在一起。更利于緩存代碼的統(tǒng)一維護。

  • Write Through, 被成為穿透寫/直寫模式--業(yè)務(wù)代碼首先調(diào)用Cache寫(新增/修改)數(shù)據(jù),然后有Cache負責(zé)寫緩存和寫SoR,不用業(yè)務(wù)代碼去寫。Write Through的特點和Read Through相仿,不過從查詢時發(fā)生變?yōu)樵诟聰?shù)據(jù)時發(fā)生。

  • Write Behind Caching,又叫Write Back。一些了解Linux操作系統(tǒng)內(nèi)核的同學(xué)對Write Back應(yīng)該非常熟悉,這不就是Linux文件系統(tǒng)的Page Cache的算法嗎?是的,你看基礎(chǔ)這玩意全都是相通的。Write Back與Write Through不同之處在于Write Back是異步寫的。說明白點就是在更新數(shù)據(jù)的時候,只更新緩存,不更新數(shù)據(jù)庫,而我們的緩存會異步地批量更新數(shù)據(jù)庫。Write Back的特點是讓數(shù)據(jù)的I/O操作飛快無比(因為直接操作內(nèi)存嘛 ),因為異步,write backg還可以合并對同一個數(shù)據(jù)的多次操作,所以性能的提高是相當(dāng)可觀的。

  • 技術(shù)選型

技術(shù) Jetedis Guava Cache Ehcache3.x
Cache-Aside 支持 支持 支持
Read Through 不支持 支持 支持
Write Through 不支持 不支持 支持
Write Behind Caching 不支持 不支持 支持

對于Cache-Aside,可能存在并發(fā)更新情況,即如果多個應(yīng)用實例同時更新那么緩存怎么辦?下一節(jié)就說明相關(guān)的關(guān)注點。

緩存架構(gòu)關(guān)注點

在緩存真正落地時可能會遇到的問題、以及這些問題的解決方法與理論有一定的隔閡,不過這種隔閡可以考驗我們的設(shè)計與架構(gòu)能力。也考驗我們深度思考的能力。

  • Dog Pile Effect

在緩存系統(tǒng)中,緩存總有失效的時候,比如我們經(jīng)常使用的 Memcache 和 Redis ,都會設(shè)置超時時間;而一旦緩存到了超時時間失效之后,如果此時再有大量的并發(fā)向數(shù)據(jù)庫發(fā)起請求,就會造成服務(wù)器卡頓甚至是系統(tǒng)當(dāng)機。這就是 Dog Pile Effect ??梢允褂肦ead Though模式進行解決。

  • 擊穿

當(dāng)請求了緩存中沒有的數(shù)據(jù)時或當(dāng)緩存服務(wù)掛掉時,這時候就會回源到DB里面。此時如果黑客故意對上面數(shù)據(jù)發(fā)起大量請求,則DB有可能會掛掉,這就是緩存擊穿。當(dāng)然緩存掛掉的話,正常的用戶請求也有可能造成緩存擊穿的效果。
最簡單的方式處理緩存擊穿問題:緩存永不過期。真正的緩存過期時間不有Redis控制,而是由程序代碼控制。當(dāng)獲取數(shù)據(jù)時發(fā)現(xiàn)數(shù)據(jù)超時時,就需要發(fā)起一個異步請求去加載數(shù)據(jù)。符合Write Back模式。

  • 可靠性

在緩存宕機的情況下,為了保證服務(wù)能夠正常的提供服務(wù)最好的方式是使用多級緩存的本地緩存進行暫時數(shù)據(jù)保存。在這其中有兩種方式選擇:白名單、布隆過濾器(Bloom Filter)。
白名單顧名思義就是:在緩存宕機之前的一段時間里,會將請求的數(shù)據(jù)在系統(tǒng)中的有無,記錄在一個Map中。當(dāng)緩存宕機后,首先在Map中判斷是否含有數(shù)據(jù),有則回源DB,沒有的話就直接返回結(jié)果。
Bloom Filter實際上是一個很長的二進制向量和一系列隨機映射函數(shù)。布隆過濾器可以用于檢索一個元素是否在一個集合中。它的優(yōu)點是空間效率和查詢時間都遠遠超過一般的算法,缺點是有一定的誤識別率和刪除困難。

  • 線程安全

保證線程安全的模式Copy Pattern。Copy Pattern包括兩種Copy-On-Read(在讀時復(fù)制)和Copy-On-Write(在寫實復(fù)制),很多本地緩存技術(shù)都是基于堆緩存中對象飲用方式。這樣就會導(dǎo)致如果有一個請求獲取了緩存數(shù)據(jù)并修改它,則可能發(fā)生不可預(yù)測的問題。所以,就需要使用COR或COW進行。

解決方案

對于緩存系統(tǒng)來說就是為了提高系統(tǒng)的并發(fā)能力。在前面幾篇文章過后大家也對緩存系統(tǒng)有了深入的認知,在此基礎(chǔ)上提出一個終極緩存架構(gòu)設(shè)計方案:


緩存終極架構(gòu)

在上面的架構(gòu)中將OpenResty和Redis推到最前端,將服務(wù)押后到Redis之后。對于分布式緩存,我們需要在OpenResty應(yīng)用中盡享應(yīng)用混存來減少Redis集群的訪問沖擊,即首先查詢OpenResty本地緩存,如果命中則直接返回,如果沒有則接著查詢Redis集群,如果在沒有則進行回溯查詢。

架構(gòu)中將Redis視為存儲,而非緩存。使用幾乎全量緩存的方式,將數(shù)據(jù)加入到緩存系統(tǒng)中。每個請求直接使用Nginx緩存或Redis緩存進行返回,不需要通過任何后臺服務(wù)、數(shù)據(jù)庫即可完成請求的處理。這樣最大限度的降低請求處理時間,最大限度的加大并發(fā)數(shù)。

  • CQRS

綜上所有的幾乎就是一個CQRS系統(tǒng)。將該隔離的隔離開,將該耦合的耦合上去。這樣就能更好的幫助我們形成一個完善的緩存架構(gòu)。


CQRS

總結(jié)

緩存是支持高并發(fā)的已經(jīng)很好的處理方式。不過要使用好緩存還是很考驗研發(fā)人員能力的。從使用Redis、Memcache作為存儲使用,還是作為緩存使用就是可以區(qū)分出一個人對于緩存的認知。所以,不要對任何一門技術(shù)設(shè)限,他不應(yīng)該只是它本來擅長的位置體現(xiàn)作用。應(yīng)該將技術(shù)擴展到其他可以滿足技術(shù)特性的場景中去。

參考

緩存雙寫不一致問題
分布式緩存擊穿(布隆過濾器 Bloom Filter)
緩存更新的套路
不懂多級緩存的分層架構(gòu)?那就看看這個吧!
CDN的本質(zhì)—大規(guī)模分布式多級緩存系統(tǒng)
如何處理 Dog Pile Effect
CQRS實踐(1): 什么是CQRS
OpenResty? - 中文官方站

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容