最近在學(xué)習(xí)整理軟件架構(gòu)中的三級(jí)緩存架構(gòu)脸侥,使用SpringBoot+Redis+MemCache+Nginx+Lua來實(shí)現(xiàn)該架構(gòu)體系镜沽,來提高系統(tǒng)的并發(fā)訪問能力茵乱,該三級(jí)緩存架構(gòu)主要適用于對(duì)請(qǐng)求并發(fā)量比較高的數(shù)據(jù)變動(dòng)不是很大的業(yè)務(wù)場(chǎng)景
三級(jí)緩存架構(gòu)
在博文開始的時(shí)候,這里我們需要了解下本博文說的三級(jí)緩存架構(gòu)是什么搜变?
首先確定一點(diǎn)采缚,本博文中的三級(jí)緩存不是我們學(xué)硬件時(shí)的三級(jí)緩存,而是在軟件開發(fā)過程中挠他,在互聯(lián)網(wǎng)的項(xiàng)目中扳抽,通常都是為了解決某些特定業(yè)務(wù)場(chǎng)景中請(qǐng)求并發(fā)量比較大,與數(shù)據(jù)庫請(qǐng)求多的問題殖侵,為了減少請(qǐng)求直接訪問數(shù)據(jù)庫的次數(shù)贸呢,通過降低訪問數(shù)據(jù)庫的次數(shù)來減輕數(shù)據(jù)庫的壓力,那如何減輕呢拢军?
那就是使用緩存了楞陷,請(qǐng)求過來之后,先從緩存中查詢茉唉,如果緩存查詢到了固蛾,就直接返回结执,否則再從數(shù)據(jù)庫中加載最新的數(shù)據(jù)到緩存中,然后再返回給數(shù)據(jù)魏铅,這樣的話昌犹,維護(hù)好緩存就能解決數(shù)據(jù)庫的壓力了。
集成緩存需要考慮的問題
了解到了我們?yōu)槭裁匆褂镁彺胬婪迹约熬彺婺芙鉀Q我們什么樣的問題。但是使用緩存時(shí)也需要注意一些問題:
如果只是單純的整合Redis緩存鸿竖,那么可能出現(xiàn)如下的問題
- 熱點(diǎn)數(shù)據(jù)的大量訪問沧竟,能對(duì)系統(tǒng)造成各種網(wǎng)絡(luò)開銷,影響系統(tǒng)的性能
- 離散的數(shù)據(jù)的訪問缚忧,可以使用Redis緩存來支撐悟泵,但是一旦緩存發(fā)生雪崩了,或者緩存被擊穿了闪水,能造成數(shù)據(jù)庫的壓力增大糕非,可能會(huì)被打死,造成數(shù)據(jù)庫掛機(jī)狀態(tài)球榆,進(jìn)而造成服務(wù)宕機(jī)
- 緩存雪崩朽肥,訪問全部打在數(shù)據(jù)庫上,數(shù)據(jù)庫也可能會(huì)被打死
為了解決以上可能出現(xiàn)的問題持钉,讓緩存層更穩(wěn)定衡招,健壯,我們使用三級(jí)緩存架構(gòu)
- Nginx層緩存
對(duì)于高并發(fā)的請(qǐng)求每强,Nginx層有著巨大的作用始腾,能反向代理,負(fù)載均衡空执,動(dòng)靜分離以及和Lua整合浪箭,可以實(shí)現(xiàn)請(qǐng)求定向分發(fā)等非常有用的功能,同理Nginx層可以實(shí)現(xiàn)緩存的功能
在我們的三級(jí)緩存架構(gòu)中辨绊,Nginx本地緩存奶栖,主要是用于承載熱數(shù)據(jù)的高并發(fā)訪問,在Nginx中通過其他技術(shù)的輔助邢羔,判斷哪些數(shù)據(jù)是熱點(diǎn)數(shù)據(jù)驼抹,然后將熱點(diǎn)數(shù)據(jù)緩存在Nginx本地緩存,當(dāng)請(qǐng)求過來時(shí)拜鹤,判斷本地緩存中是否存在框冀,如果存在著直接返回請(qǐng)求結(jié)果(或者展現(xiàn)靜態(tài)資源的數(shù)據(jù)),這樣的請(qǐng)求不會(huì)直接發(fā)送到后端服務(wù)層敏簿,請(qǐng)求的并發(fā)量完全取決于Nginx的并發(fā)量
其次明也,Nginx層也可以通過自身的策略配置宣虾,可以過濾一些惡意請(qǐng)求,或者限制某些IP的訪問都是有些不小的作用
- Redis層緩存
當(dāng)然温数,并不是所有的數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù)绣硝,大部分還是一些離散數(shù)據(jù),再加上Nginx層的數(shù)據(jù)也有失效時(shí)間撑刺,當(dāng)Nginx層數(shù)據(jù)失效了鹉胖,還得從服務(wù)中獲取最新的數(shù)據(jù)。
Redis有很多的優(yōu)勢(shì)够傍,支持分布式大規(guī)模緩存甫菠,支持海量數(shù)據(jù),高并發(fā)的訪問和高可用的服務(wù)冕屯,方便橫向擴(kuò)展來擴(kuò)大數(shù)據(jù)量寂诱,同時(shí)Redis可以配置高可用,對(duì)于系統(tǒng)的穩(wěn)定性安聘,有著不言而喻的優(yōu)勢(shì)
- Tomcat堆緩存
Tomcat堆緩存痰洒,主要是抗Redis大規(guī)模災(zāi)難,如果Redis出現(xiàn)大規(guī)模的宕機(jī)浴韭,導(dǎo)致Nginx請(qǐng)求直接涌入數(shù)據(jù)生產(chǎn)服務(wù)丘喻,name我們最后的Tomcat緩存至少可以再抗一下,不至于讓數(shù)據(jù)庫直接裸奔
同時(shí)tomcat jvm堆內(nèi)存緩存囱桨,也可以抗住redis沒有cache住的最后那少量的部分緩存
- 用戶請(qǐng)求過來仓犬,首先經(jīng)過Nginx層,Nginx層這里分為雙層舍肠,一層作為分發(fā)層搀继,一層作為應(yīng)用層
- 分發(fā)層集成Lua,來請(qǐng)求定向(針對(duì)同一請(qǐng)求固定打到某一服務(wù)上)翠语,另一層做數(shù)據(jù)緩存
- 如果請(qǐng)求在Nginx的應(yīng)用層找不到數(shù)據(jù)叽躯,則直接請(qǐng)求到后臺(tái)服務(wù)系統(tǒng),服務(wù)系統(tǒng)到Redis緩存中查詢數(shù)據(jù)
- Redis中請(qǐng)求到數(shù)據(jù)直接返回Nginx層肌括,同時(shí)將數(shù)據(jù)緩存到Nginx層中
- Redis中查詢不到數(shù)據(jù)点骑,則從Tomcat堆緩存中查詢數(shù)據(jù),如果查詢到則直接返回谍夭,同時(shí)將數(shù)據(jù)緩存到Reids和Nginx的緩存中
- Tomcat堆緩存中查詢不到數(shù)據(jù)黑滴,則直接請(qǐng)求數(shù)據(jù)庫,然后返回紧索,將數(shù)據(jù)緩存到Tomcat堆緩存袁辈、Redis緩存和Nginx緩存中
- 這樣的話數(shù)據(jù)庫的壓力就會(huì)非常小了,再加上Ridis的QPS很高珠漂,所以整個(gè)服務(wù)的性能就比較好了
當(dāng)然三級(jí)緩存架構(gòu)模式只適用于數(shù)據(jù)變動(dòng)不是很大晚缩,但請(qǐng)求并發(fā)量比較大的場(chǎng)景尾膊,針對(duì)數(shù)據(jù)變動(dòng)變動(dòng)的處理,可以參考我的博文 緩存與數(shù)據(jù)庫雙寫一致性的解決方案——附上代碼解決方案
下一篇博文我們?cè)俑鶕?jù)我們的三級(jí)緩存架構(gòu)模型荞彼,來搭建我們需要的系統(tǒng)環(huán)境:搭建Nginx冈敛、Redis集群、SpringBoot集成Memcache緩存以及數(shù)據(jù)庫安裝等鸣皂,然后基于此環(huán)境來編碼實(shí)現(xiàn)簡(jiǎn)單的場(chǎng)景交互功能