不用緩存服務(wù),還能怎么緩存數(shù)據(jù)?架構(gòu)師之路關(guān)注共 1630字,需瀏覽 4分鐘 ·2021-01-18 08:54 除了常見的redis/memcache等進(jìn)程外緩存服務(wù),還能怎么緩存數(shù)據(jù)?緩存還有一種常見的玩法,進(jìn)程內(nèi)緩存。什么是進(jìn)程內(nèi)緩存?將一些數(shù)據(jù)緩存在站點(diǎn),或者服務(wù)的進(jìn)程內(nèi),這就是進(jìn)程內(nèi)緩存。進(jìn)程內(nèi)緩存的實(shí)現(xiàn)載體,最簡單的,可以是一個(gè)帶鎖的Map。又或者,可以使用第三方庫,例如leveldb。進(jìn)程內(nèi)緩存能存儲(chǔ)啥?redis/memcache等進(jìn)程外緩存服務(wù)能存什么,進(jìn)程內(nèi)緩存就能存什么。如上圖,可以存儲(chǔ)json數(shù)據(jù),可以存儲(chǔ)html頁面,可以存儲(chǔ)對(duì)象。進(jìn)程內(nèi)緩存有什么好處?與沒有緩存相比,進(jìn)程內(nèi)緩存的好處是,數(shù)據(jù)讀取不再需要訪問后端,例如數(shù)據(jù)庫。如上圖,整個(gè)訪問流程要經(jīng)過1,2,3,4四個(gè)步驟。如果引入進(jìn)程內(nèi)緩存,如上圖,整個(gè)訪問流程只要經(jīng)過1,2兩個(gè)步驟。與進(jìn)程外緩存相比(例如redis/memcache),進(jìn)程內(nèi)緩存省去了網(wǎng)絡(luò)開銷,所以一來節(jié)省了內(nèi)網(wǎng)帶寬,二來響應(yīng)時(shí)延會(huì)更低。進(jìn)程內(nèi)緩存有什么缺點(diǎn)?統(tǒng)一緩存服務(wù)雖然多一次網(wǎng)絡(luò)交互,但仍是統(tǒng)一存儲(chǔ)。如上圖,站點(diǎn)和服務(wù)中的多個(gè)節(jié)點(diǎn)訪問統(tǒng)一的緩存服務(wù),數(shù)據(jù)統(tǒng)一存儲(chǔ),容易保證數(shù)據(jù)的一致性。而進(jìn)程內(nèi)緩存,如上圖,如果數(shù)據(jù)緩存在站點(diǎn)和服務(wù)的多個(gè)節(jié)點(diǎn)內(nèi),數(shù)據(jù)存了多份,一致性比較難保障。如何保證進(jìn)程內(nèi)緩存的數(shù)據(jù)一致性?保障進(jìn)程內(nèi)緩存一致性,有幾種方案。第一種方案,可以通過單節(jié)點(diǎn)通知其他節(jié)點(diǎn)。如上圖:寫請(qǐng)求發(fā)生在server1,在修改完自己內(nèi)存數(shù)據(jù)與數(shù)據(jù)庫中的數(shù)據(jù)之后,可以主動(dòng)通知其他server節(jié)點(diǎn),也修改內(nèi)存的數(shù)據(jù)。這種方案的缺點(diǎn)是:同一功能的一個(gè)集群的多個(gè)節(jié)點(diǎn),相互耦合在一起,特別是節(jié)點(diǎn)較多時(shí),網(wǎng)狀連接關(guān)系極其復(fù)雜。第二種方案,可以通過MQ通知其他節(jié)點(diǎn)。如上圖,寫請(qǐng)求發(fā)生在server1,在修改完自己內(nèi)存數(shù)據(jù)與數(shù)據(jù)庫中的數(shù)據(jù)之后,給MQ發(fā)布數(shù)據(jù)變化通知,其他server節(jié)點(diǎn)訂閱MQ消息,也修改內(nèi)存數(shù)據(jù)。這種方案雖然解除了節(jié)點(diǎn)之間的耦合,但引入了MQ,使得系統(tǒng)更加復(fù)雜。前兩種方案,節(jié)點(diǎn)數(shù)量越多,數(shù)據(jù)冗余份數(shù)越多,數(shù)據(jù)同時(shí)更新的原子性越難保證,一致性也就越難保證。第三種方案,為了避免耦合,降低復(fù)雜性,干脆放棄了“實(shí)時(shí)一致性”,每個(gè)節(jié)點(diǎn)啟動(dòng)一個(gè)timer,定時(shí)從后端拉取最新的數(shù)據(jù),更新內(nèi)存緩存。在有節(jié)點(diǎn)更新后端數(shù)據(jù),而其他節(jié)點(diǎn)通過timer更新數(shù)據(jù)之間,會(huì)讀到臟數(shù)據(jù)。為什么不能頻繁使用進(jìn)程內(nèi)緩存?分層架構(gòu)設(shè)計(jì),有一條準(zhǔn)則:站點(diǎn)層、服務(wù)層要做到無數(shù)據(jù)無狀態(tài),這樣才能任意的加節(jié)點(diǎn)水平擴(kuò)展,數(shù)據(jù)和狀態(tài)盡量存儲(chǔ)到后端的數(shù)據(jù)存儲(chǔ)服務(wù),例如數(shù)據(jù)庫服務(wù)或者緩存服務(wù)。可以看到,站點(diǎn)與服務(wù)的進(jìn)程內(nèi)緩存,實(shí)際上違背了分層架構(gòu)設(shè)計(jì)的無狀態(tài)準(zhǔn)則,故一般不推薦使用。什么時(shí)候可以使用進(jìn)程內(nèi)緩存?以下情況,可以考慮使用進(jìn)程內(nèi)緩存。情況一,只讀數(shù)據(jù),可以考慮在進(jìn)程啟動(dòng)時(shí)加載到內(nèi)存。畫外音:此時(shí)也可以把數(shù)據(jù)加載到redis / memcache,進(jìn)程外緩存服務(wù)也能解決這類問題。情況二,極其高并發(fā)的,如果透傳后端壓力極大的場景,可以考慮使用進(jìn)程內(nèi)緩存。例如,秒殺業(yè)務(wù),并發(fā)量極高,需要站點(diǎn)層擋住流量,可以使用內(nèi)存緩存。情況三,一定程度上允許數(shù)據(jù)不一致業(yè)務(wù)。例如,有一些計(jì)數(shù)場景,運(yùn)營場景,頁面對(duì)數(shù)據(jù)一致性要求較低,可以考慮使用進(jìn)程內(nèi)頁面緩存。末了,再次強(qiáng)調(diào),進(jìn)程內(nèi)緩存的適用場景并不如redis/memcache廣泛,不要為了炫技而使用。更多的時(shí)候,還是老老實(shí)實(shí)使用redis/mc吧。畫外音:額,介紹技術(shù),不希望把大家?guī)恕?/em>架構(gòu)師之路-分享技術(shù)思路相關(guān)推薦:《很多人問,到底要不要轉(zhuǎn)管理?》《群消息,究竟存1份還是多份?》任何脫離業(yè)務(wù)的架構(gòu)設(shè)計(jì)都是耍流氓。希望大家有收獲。 瀏覽 23點(diǎn)贊 評(píng)論 收藏 分享 手機(jī)掃一掃分享分享 舉報(bào) 評(píng)論圖片表情視頻評(píng)價(jià)全部評(píng)論推薦 xHttpCacheHTTP 高速數(shù)據(jù)緩存服務(wù)xhttpcache是什么?xhttpcache?是一個(gè)HTTP高速數(shù)據(jù)緩存服務(wù),也可以做為K-V存xHttpCacheHTTP 高速數(shù)據(jù)緩存服務(wù)xhttpcache是什么?xhttpcache?是一個(gè)HTTP高速數(shù)據(jù)緩存服務(wù),也可以做為K-V存儲(chǔ)的NOSQL數(shù)據(jù)庫支持redis協(xié)議接口,支持HTTP協(xié)議的REST接口;xhttpcache有哪Redis 緩存擊穿(失效)、緩存穿透、緩存雪崩怎么解決?Hollis0進(jìn)程緩存和緩存服務(wù),如何抉擇?小哈學(xué)Java0進(jìn)程緩存和緩存服務(wù),如何抉擇?互聯(lián)網(wǎng)架構(gòu)師0進(jìn)程緩存和緩存服務(wù),如何抉擇?Java技術(shù)棧0Redis 緩存雪崩、緩存穿透、緩存擊穿、緩存降級(jí)、緩存預(yù)熱、緩存更新一個(gè)代碼搬運(yùn)工0Redis緩存問題-緩存雪崩、緩存擊穿、緩存穿透程序媛和她的貓0PDCacheJava 數(shù)據(jù)緩存工具PDCache是一個(gè)輕量級(jí),高可靠性,強(qiáng)一致性,基于java內(nèi)部Reference工具的數(shù)據(jù)緩存工具,用于在程序內(nèi)部緩存可丟失型的數(shù)據(jù)。也可用Map實(shí)現(xiàn)的根據(jù)id保存的數(shù)據(jù)或可丟失的鎖,強(qiáng)一致性的特點(diǎn)PDCacheJava 數(shù)據(jù)緩存工具PDCache 是一個(gè)輕量級(jí),高可靠性,強(qiáng)一致性,基于 java 內(nèi)部 Reference 工具的數(shù)點(diǎn)贊 評(píng)論 收藏 分享 手機(jī)掃一掃分享分享 舉報(bào)