(1)性能設計篇之 " 緩存 "

概要:

1秉氧、緩存是為了加速數(shù)據(jù)訪問址儒,在數(shù)據(jù)庫之上添加的一層機制僻焚。

2允悦、典型的緩存模式:Cache Aside、Read/Write Through 和 Write Behind Caching 以及它們各自的優(yōu)缺點虑啤。

3隙弛、緩存設計的重點,性能之外咐旧,分布式架構(gòu)下和公網(wǎng)環(huán)境下驶鹉,對緩存集群、一致性铣墨、LRU 的鎖競爭室埋、爬蟲等多方面都需要考慮。

分布式系統(tǒng)中最耗性能就是數(shù)據(jù)庫了。小心維護好姚淆,三個寫操作 insert孕蝉、update 和 delete 不太會出現(xiàn)性能問題(insert 一般不會有性能問題,update 和 delete 一般會有主鍵腌逢,所以也不會太慢)降淮。除非索引建得太多,數(shù)據(jù)又太多搏讶,這三個操作才會變慢佳鳖。

select 是性能問題最大的地方: join、group媒惕、order系吩、like 非常耗性能的;大多數(shù)都是讀多寫少妒蔚,加劇了慢查詢的問題穿挨。

遠程調(diào)用有網(wǎng)絡開銷,也會耗很多性能肴盏,會導致整體的響應時間下降科盛。使用緩存是非常必要的事情。

二菜皂、緩存三種模式

1贞绵、Cache Aside 更新模式

最常用的設計模式了,其具體邏輯如下恍飘。

失效:先從 cache 取數(shù)據(jù)但壮,沒有則從數(shù)據(jù)庫中取數(shù)據(jù),成功后常侣,放到緩存中。

命中:從 cache 中取數(shù)據(jù)弹渔,返回胳施。

更新:存到數(shù)據(jù)庫中,成功后肢专,緩存失效舞肆。

為什么不是寫完數(shù)據(jù)庫后更新緩存?怕兩個并發(fā)的寫操作導致臟數(shù)據(jù)博杖。

Cache Aside 并發(fā)問題椿胯,比如,一個是讀操作剃根,沒有命中緩存哩盲,到數(shù)據(jù)庫中取數(shù)據(jù)。此時來了一個寫操作,寫完數(shù)據(jù)庫后廉油,讓緩存失效惠险,然后之前的那個讀操作再把老的數(shù)據(jù)放進去,所以會造成臟數(shù)據(jù)抒线。

實際出現(xiàn)概率低班巩,需要發(fā)生在讀緩存時緩存失效,而且有并發(fā)的寫操作嘶炭。數(shù)據(jù)庫的寫比讀操作慢得多抱慌,還要鎖表,讀在寫前操作眨猎,又晚于寫更新緩存抑进,這些條件都具備的概率并不大。

所以宵呛,這也就是 Quora 上的那個答案里說的单匣,要么通過 2PC 或是 Paxos 協(xié)議保證一致性,要么就是拼命地降低并發(fā)時臟數(shù)據(jù)的概率宝穗。而 Facebook 使用了這個降低概率的玩法户秤,因為 2PC 太慢,而 Paxos 太復雜逮矛。當然鸡号,最好還是為緩存設置好過期時間。

2须鼎、Read/Write Through 更新模式

Cache Aside需要維護兩個數(shù)據(jù)存儲鲸伴,緩存(cache)和數(shù)據(jù)庫(repository)。

Read/Write Through 把更新數(shù)據(jù)庫(repository)的操作由緩存自己代理了晋控。對于應用層來說汞窗,簡單很多,應用認為后端就是一個單一的存儲赡译,而存儲自己維護自己的 Cache仲吏。

Read Through

查詢操作中更新緩存,當緩存失效的時候(過期或 LRU 換出)蝌焚,

Cache Aside :調(diào)用方把數(shù)據(jù)加載入緩存

Read Through :緩存服務自己來加載裹唆,對應用方是透明的。

Write Through

Write Through 和 Read Through 相仿只洒,更新:沒有命中緩存许帐,更新數(shù)據(jù)庫,返回毕谴。命中了則更新緩存成畦,由 Cache 自己更新數(shù)據(jù)庫(這是一個同步操作)距芬。

其中的 Memory,可以理解為我們例子里的數(shù)據(jù)庫羡鸥。

3.Write Behind Caching 更新模式

Write Behind 又叫 Write Back蔑穴。

更新數(shù)據(jù)的時候,只更新緩存惧浴,不更新數(shù)據(jù)庫存和,緩存會異步地批量更新數(shù)據(jù)庫。讓數(shù)據(jù)的 I/O 操作飛快無比(因為直接操作內(nèi)存嘛)衷旅。因為異步捐腿,還可以合并對同一個數(shù)據(jù)的多次操作,性能提高柿顶。

數(shù)據(jù)不是強一致性的茄袖,而且可能會丟失。強一致性和高性能嘁锯,高可用和高性能是有沖突的宪祥。

實現(xiàn)邏輯復雜,需要 track哪些數(shù)據(jù)是被更新了的家乘,刷到持久層上蝗羊。僅當這個 cache 需要失效的時候,才會把它真正持久起來仁锯。比如耀找,內(nèi)存不夠了,或是進程退出了等情況业崖,這又叫 lazy write野芒。

Write Back 的流程圖

三、緩存設計的重點

用Redis 原因:(1)數(shù)據(jù)結(jié)構(gòu)豐富双炕。(2)不能在 Service 內(nèi)放 local cache狞悲,Service 有多個實例,負載均衡器會把請求隨機分布到不同的實例妇斤。緩存需要在所有的 Service 實例上都建好效诅,Service 有狀態(tài),更難管理了趟济。

分布式架構(gòu)下,需要一個外部的緩存集群咽笼,要內(nèi)存要足夠大顷编,網(wǎng)絡帶寬也要好,因為緩存本質(zhì)上是個內(nèi)存和 IO 密集型的應用剑刑。

內(nèi)存很大媳纬,要數(shù)據(jù)分片把不同的緩存分布到不同的機器上双肤。保證緩存集群可以不斷地 scale 下去。

緩存的命中率高說明緩存有效钮惠,80% 以上就算很高了茅糜。有的為了追求更高的性能,95% 以上素挽,甚至100%蔑赘。不必要的,也沒效率的预明,熱點數(shù)據(jù)只會是少數(shù)缩赛。

時間周期太長太短都不好,過期期限不宜太短撰糠,導致不斷從數(shù)據(jù)存儲檢索數(shù)據(jù)添加到緩存酥馍。不宜太長,冷數(shù)據(jù)不過期浪費內(nèi)存阅酪。

LRU 策略:內(nèi)存不夠時旨袒,清除不活躍數(shù)據(jù)。在 key-value 這樣的非順序的數(shù)據(jù)結(jié)構(gòu)中維護一個順序的數(shù)據(jù)結(jié)構(gòu)术辐,讀緩存時改變排位砚尽。所以LRU 在讀寫都加鎖(除非是單線程無并發(fā)),會導致更的緩存存取的時間术吗。

網(wǎng)站都會被爬蟲爬尉辑,爬蟲可能會爬到一些很古老的數(shù)據(jù),把這些數(shù)據(jù)加到緩存较屿,熱點數(shù)據(jù)被擠出去(因為機器的速度足夠快)隧魄。需要有爬蟲保護機制,引導這些人去使用我們外部 API隘蝎。針對性地做多租戶的緩存系統(tǒng)(也就是說购啄,把用戶和第三方開發(fā)者的緩存系統(tǒng)分離開來)。

你接觸到的緩存方式有哪些嘱么?怎樣權(quán)衡一致性和緩存的效率狮含?

評論1:

Read/Write Through 模式中對數(shù)據(jù)庫的操作一定要交給交給緩存代理么,如果是這樣就會帶來兩個問題:

1. 需要在緩存服務中實現(xiàn)數(shù)據(jù)庫操作的代碼曼振,主流緩存是否支持這樣的操作几迄。

2. 緩存與數(shù)據(jù)庫之間建立了依賴。

常見的做法是由應用服務操作緩存以及數(shù)據(jù)庫冰评,跟cache aside模式很像了映胁。

評論2:

redis 分片熱點問題,有沒有什么好的解決方案甲雅?建數(shù)據(jù)索引服務

評論3:

Cache aside 需要處理并發(fā)讀問題解孙,緩存失效時多個讀會打到數(shù)據(jù)庫坑填,怎么解決?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末弛姜,一起剝皮案震驚了整個濱河市脐瑰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌廷臼,老刑警劉巖苍在,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異中剩,居然都是意外死亡忌穿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門结啼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掠剑,“玉大人,你說我怎么就攤上這事郊愧∑右耄” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵属铁,是天一觀的道長眠寿。 經(jīng)常有香客問我,道長焦蘑,這世上最難降的妖魔是什么盯拱? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮例嘱,結(jié)果婚禮上狡逢,老公的妹妹穿的比我還像新娘。我一直安慰自己拼卵,他們只是感情好奢浑,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著腋腮,像睡著了一般雀彼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上即寡,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天徊哑,我揣著相機與錄音,去河邊找鬼聪富。 笑死实柠,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的善涨。 我是一名探鬼主播窒盐,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼钢拧!你這毒婦竟也來了蟹漓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤源内,失蹤者是張志新(化名)和其女友劉穎葡粒,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膜钓,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡嗽交,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了颂斜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片夫壁。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖沃疮,靈堂內(nèi)的尸體忽然破棺而出盒让,到底是詐尸還是另有隱情,我是刑警寧澤司蔬,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布邑茄,位于F島的核電站,受9級特大地震影響俊啼,放射性物質(zhì)發(fā)生泄漏肺缕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一授帕、第九天 我趴在偏房一處隱蔽的房頂上張望同木。 院中可真熱鬧,春花似錦豪墅、人聲如沸泉手。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽斩萌。三九已至,卻和暖如春屏轰,著一層夾襖步出監(jiān)牢的瞬間颊郎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工霎苗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留姆吭,地道東北人。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓唁盏,卻偏偏與公主長得像内狸,于是被迫代替她去往敵國和親检眯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 31,905評論 2 89
  • 理論總結(jié) 它要解決什么樣的問題昆淡? 數(shù)據(jù)的訪問锰瘸、存取、計算太慢昂灵、太不穩(wěn)定避凝、太消耗資源,同時眨补,這樣的操作存在重復性管削。因...
    jiangmo閱讀 2,842評論 0 11
  • 1- 緩存與數(shù)據(jù)庫 應用程序通常使用緩存來提高系統(tǒng)系能,特別是對于只讀事務來說撑螺。當數(shù)據(jù)發(fā)生變化時含思,這些應用程序會直...
    zhanglbjames閱讀 1,974評論 0 3
  • 做戰(zhàn)略就是滑向球要去的地方而不是球在的地方。 戰(zhàn)略的核心是回答如何思考增長实蓬。從經(jīng)營上來講機會不一定很多茸俭,但從戰(zhàn)略的...
    郭強GQ閱讀 681評論 0 1
  • 2018年1月28日 星期日 臘月十二 小雪 今天,迫不及想著出院安皱,在醫(yī)院一下子覺著憔悴了許多调鬓。無規(guī)律的生活,無法...
    菊花與刀的夢閱讀 153評論 0 0