掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
自古兵家多謀,《謀攻篇》,“故上兵伐謀,其次伐交,其次伐兵,其下攻城。攻城之法,為不得已”,可見攻城之計(jì)有很多種,而爬墻攻城是最不明智的做法,軍隊(duì)疲憊受損、錢糧損耗、百姓遭殃。故而我們有很多迂回之策,謀略、外交、軍事手段等等,每一種都比攻城的代價(jià)小,更輕量級(jí),緩存設(shè)計(jì)亦是如此。

創(chuàng)新互聯(lián)專注于企業(yè)成都營銷網(wǎng)站建設(shè)、網(wǎng)站重做改版、雙陽網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5高端網(wǎng)站建設(shè)、商城網(wǎng)站開發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為雙陽等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
為什么要設(shè)計(jì)緩存呢?
其實(shí)高并發(fā)應(yīng)對(duì)的解決方案不是互聯(lián)網(wǎng)***的,計(jì)算機(jī)先祖?zhèn)兒茉缇蛯?duì)類似的場(chǎng)景做了方案。比如《計(jì)算機(jī)組成原理》這樣提到的cpu緩存概念,它是一種高速緩存,容量比內(nèi)存小但是速度卻快很多,這種緩存的出現(xiàn)主要是為了解決cpu運(yùn)算速度遠(yuǎn)大于內(nèi)存讀寫速度,甚至達(dá)到千萬倍。
傳統(tǒng)的cpu通過fsb直連內(nèi)存的方式顯然就會(huì)因?yàn)閮?nèi)存訪問的等待,導(dǎo)致cpu吞吐量下降,內(nèi)存成為性能瓶頸。同時(shí)又由于內(nèi)存訪問的熱點(diǎn)數(shù)據(jù)集中性,所以需要在cpu與內(nèi)存之間做一層臨時(shí)的存儲(chǔ)器作為高速緩存。
隨著系統(tǒng)復(fù)雜性的提升,這種高速緩存和內(nèi)存之間的速度進(jìn)一步拉開,由于技術(shù)難度和成本等原因,所以有了更大的二級(jí)、三級(jí)緩存。根據(jù)讀取順序,絕大多數(shù)的請(qǐng)求首先落在一級(jí)緩存上,其次二級(jí)...
故而應(yīng)用于SOA甚至微服務(wù)的場(chǎng)景,內(nèi)存相當(dāng)于存儲(chǔ)業(yè)務(wù)數(shù)據(jù)的持久化數(shù)據(jù)庫,其吞吐量肯定是遠(yuǎn)遠(yuǎn)小于緩存的,而對(duì)于java程序來講,本地的jvm緩存優(yōu)于集中式的redis緩存。
關(guān)系型數(shù)據(jù)庫操作方便、易于維護(hù)且訪問數(shù)據(jù)靈活,但是隨著數(shù)據(jù)量的增加,其檢索、更新的效率會(huì)越來越低。所以在高并發(fā)低延遲要求復(fù)雜的場(chǎng)景,要給數(shù)據(jù)庫減負(fù),減少其壓力。
給數(shù)據(jù)庫減負(fù)
1. 緩存分布式,做多級(jí)緩存
(1) 讀請(qǐng)求時(shí)寫緩存
寫緩存時(shí)一級(jí)一級(jí)寫,先寫本地緩存,再寫集中式緩存。具體些緩存的方法可以有很多種,但是需要注意幾項(xiàng)原則:
綜上所述,高耦合帶來的痛,彌補(bǔ)的代價(jià)是很大的,所以可以借鑒Spring cache來實(shí)現(xiàn),實(shí)現(xiàn)也比較簡單,使用時(shí)一個(gè)注解就搞定了。
(2) 寫緩存失敗了怎么辦?應(yīng)該先寫緩存還是數(shù)據(jù)庫呢?
既然是緩存的設(shè)計(jì),那么策略一定是保證最終一致性,那么我們只需要采用異步消息來補(bǔ)償就好了。
大部分緩存應(yīng)用的場(chǎng)景是讀寫比差異很大的,讀遠(yuǎn)大于寫,在這種場(chǎng)景下,只需要以數(shù)據(jù)庫為主,先寫數(shù)據(jù)庫,再寫緩存就好了。
***補(bǔ)充一點(diǎn),數(shù)據(jù)庫出現(xiàn)異常時(shí),不要一股腦的catch RuntimeException,而是把具體關(guān)心的異常往外拋,然后進(jìn)行有針對(duì)性的異常處理。
(3) 關(guān)于其他性能方面
緩存設(shè)計(jì)都是占用越少越好,內(nèi)存資源昂貴以及太大不好維護(hù)都驅(qū)使我們這樣設(shè)計(jì)。所以要盡可能減少緩存不必要的數(shù)據(jù),有的同學(xué)圖省事把整個(gè)對(duì)象序列化存儲(chǔ)。另外,序列化與反序列化也是消耗性能的。
2. vs各種緩存同步方案
緩存同步方案有很多種,在考慮一致性、數(shù)據(jù)庫訪問壓力、實(shí)時(shí)性等方面做權(quán)衡。總的來說有以下幾種方式:
(1) 懶加載式
如上段提到的方式,讀時(shí)順便加載。為了更新緩存數(shù)據(jù),需要過期緩存。
優(yōu)點(diǎn):簡單直接
缺點(diǎn):
懶加載式太簡單了,沒有自動(dòng)加載,異步刷新等機(jī)制,為了彌補(bǔ)其缺陷,請(qǐng)參見接下來的兩種方法。
(2) 補(bǔ)充式
可以在緩存時(shí),把過期時(shí)間等信息寫到一個(gè)異步隊(duì)列里,后臺(tái)起個(gè)線程池定期掃描這個(gè)隊(duì)列,在快過期時(shí)主動(dòng)reload緩存,使得數(shù)據(jù)會(huì)一直保持在緩存中,如果緩存沒有也沒有必要去數(shù)據(jù)庫查詢了。常見的處理方式有使用binlog加工成消息供增量處理。
(3) 定時(shí)加載式
這就需要有個(gè)異步線程池定期把數(shù)據(jù)庫的數(shù)據(jù)刷到集中式緩存,如redis里。
3. 防止緩存穿透
緩存穿透是指查詢的key壓根不存在,從而緩存查詢不到而查詢了數(shù)據(jù)庫。若是這樣的key恰好并發(fā)請(qǐng)求很大,那么就會(huì)對(duì)數(shù)據(jù)庫造成不必要的壓力。怎么解決呢?
4. 熱點(diǎn)緩存與緩存淘汰策略
有一些場(chǎng)景,需要只保持一部分的熱點(diǎn)緩存,不需要全量緩存,比如熱賣的商品信息,購買某類商品的熱門商圈信息等等。
綜合來講,緩存過期的策略有以下三種:
(1) FIFO(First In,F(xiàn)irst Out)
先進(jìn)先出,淘汰最早進(jìn)來的緩存數(shù)據(jù),一個(gè)標(biāo)準(zhǔn)的隊(duì)列。
以隊(duì)列為基本數(shù)據(jù)結(jié)構(gòu),從隊(duì)首進(jìn)入新數(shù)據(jù),從隊(duì)尾淘汰。
(2) LRU(Least RecentlyUsed)
最近最少使用,淘汰最近不使用的緩存數(shù)據(jù)。如果數(shù)據(jù)最近被訪問過,則不淘汰。
(3) LFU(Least Frequently used)
最近使用次數(shù)最少的數(shù)據(jù)被淘汰,注意和LRU的區(qū)別在于LRU的淘汰規(guī)則是基于訪問時(shí)間。
4. 緩存使用的一些常見問題
Q:那么應(yīng)該選擇用本地緩存(local cache)還是集中式緩存(Cache cluster)呢?
A:首先看數(shù)據(jù)量,看緩存更新的成本,如果整體緩存數(shù)據(jù)量不是很大,而且變化的不頻繁,那么建議本地緩存。
Q:怎么批量更新一批緩存數(shù)據(jù)?
A:依次從數(shù)據(jù)庫讀取,然后批量寫入緩存,批量更新,設(shè)置版本過期key或者主動(dòng)刪除。
Q:如果不知道有哪些key怎么定期刪除?
A:拿redis來說keys * 太損耗性能,不推薦。可以指定一個(gè)集合,把所有的key都存到這個(gè)集合里,然后對(duì)整個(gè)集合進(jìn)行刪除,這樣便能完全清理了。
Q:一個(gè)key包含的集合很大,redis無法做到內(nèi)存空間上的均勻Shard?
A:可以簡單的設(shè)置key過期,這樣就要允許有緩存不***的情況;給key設(shè)置版本,比如為兩天后的當(dāng)前時(shí)間,然后讀取緩存時(shí)用時(shí)間判斷一下是否需要重新加載緩存,作為版本過期的策略。
王梓晨:物流研發(fā)部架構(gòu)師,GIS技術(shù)部負(fù)責(zé)人,2012年加入京東,多年一線團(tuán)隊(duì)大促備戰(zhàn)經(jīng)驗(yàn),負(fù)責(zé)物流研發(fā)一些部門的架構(gòu)工作,專注于低延遲系統(tǒng)設(shè)計(jì)與海量數(shù)據(jù)處理。曾負(fù)責(zé)青龍配送分單團(tuán)隊(duì),主導(dǎo)重構(gòu)架構(gòu)設(shè)計(jì)與主要研發(fā)工作,短期內(nèi)提升了服務(wù)性能數(shù)十倍。還設(shè)計(jì)研發(fā)了地址配送網(wǎng)點(diǎn)分類模型,實(shí)現(xiàn)了配送到路區(qū)的精準(zhǔn)化分單,降本增效,大幅提升了自動(dòng)分單準(zhǔn)確率。目前負(fù)責(zé)物流GIS部門,先后主導(dǎo)了國標(biāo)轉(zhuǎn)京標(biāo)、物流可視化等項(xiàng)目。
【本文來自專欄作者張開濤的微信公眾號(hào)(開濤的博客),公眾號(hào)id: kaitao-1234567】

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流