分布式緩存的最佳實踐案例分析_第1頁
分布式緩存的最佳實踐案例分析_第2頁
分布式緩存的最佳實踐案例分析_第3頁
分布式緩存的最佳實踐案例分析_第4頁
分布式緩存的最佳實踐案例分析_第5頁
已閱讀5頁,還剩12頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、 分布式緩存的最佳實踐案例分析本文主要介紹使用分布式緩存的優(yōu)秀實踐和線上案例。這些案例是筆者在多家互聯(lián)網(wǎng)公司里積累并形成的優(yōu)秀實踐,能夠幫助大家在生產(chǎn)實踐中避免很多不必要的生產(chǎn)事故。一、緩存設(shè)計的核心要素我們在應(yīng)用中決定使用緩存時,通常需要進行詳細的設(shè)計,因為設(shè)計緩存架構(gòu)看似簡單,實則不然,里面蘊含了很多深奧的原理,如果使用不當,則會造成很多生產(chǎn)事故甚至是服務(wù)雪崩之類的嚴重問題。筆者在做設(shè)計評審的過程中,總結(jié)了所有與緩存設(shè)計相關(guān)的設(shè)計點,這里列出來供大家參考。1、容量規(guī)劃緩存內(nèi)容的大小緩存內(nèi)容的數(shù)量淘汰策略緩存的數(shù)據(jù)結(jié)構(gòu)每秒的讀峰值每秒的寫峰值2、性能優(yōu)化線程模型預熱方法緩存分片冷熱數(shù)據(jù)的比例

2、3、高可用復制模型失效轉(zhuǎn)移持久策略緩存重建4、緩存監(jiān)控緩存服務(wù)監(jiān)控緩存容量監(jiān)控緩存請求監(jiān)控緩存響應(yīng)時間監(jiān)控5、注意事項是否有可能發(fā)生緩存穿透是否有大對象是否使用緩存實現(xiàn)分布式鎖是否使用緩存支持的腳本(Lua)是否避免了Race Condition筆者在這里把這些設(shè)計點提供給讀者,請讀者在做緩存設(shè)計時把每一項作為一個思考的起點,思考我們在設(shè)計緩存時是否想到了這些點,以避免在設(shè)計的過程中因忽略某一項而導致嚴重的線上事故發(fā)生。二、緩存設(shè)計的優(yōu)秀實踐筆者在做設(shè)計評審的過程中,總結(jié)了一些開發(fā)人員在設(shè)計緩存系統(tǒng)時的優(yōu)秀實踐,如下所述:優(yōu)秀實踐1緩存系統(tǒng)主要消耗的是服務(wù)器的內(nèi)存,因此,在使用緩存時必須先對應(yīng)

3、用需要緩存的數(shù)據(jù)大小進行評估,包括緩存的數(shù)據(jù)結(jié)構(gòu)、緩存大小、緩存數(shù)量、緩存的失效時間,然后根據(jù)業(yè)務(wù)情況自行推算在未來一定時間內(nèi)的容量的使用情況,根據(jù)容量評估的結(jié)果來申請和分配緩存資源,否則會造成資源浪費或者緩存空間不夠。優(yōu)秀實踐2建議將使用緩存的業(yè)務(wù)進行分離,核心業(yè)務(wù)和非核心業(yè)務(wù)使用不同的緩存實例,從物理上進行隔離,如果有條件,則請對每個業(yè)務(wù)使用單獨的實例或者集群,以減小應(yīng)用之間互相影響的可能性。筆者就經(jīng)常聽說有的公司應(yīng)用了共享緩存,造成緩存數(shù)據(jù)被覆蓋以及緩存數(shù)據(jù)錯亂的線上事故。優(yōu)秀實踐3根據(jù)緩存實例提供的內(nèi)存大小推算應(yīng)用需要使用的緩存實例數(shù)量,一般在公司里會成立一個緩存管理的運維團隊,這個團

4、隊會將緩存資源虛擬成多個相同內(nèi)存大小的緩存實例。例如一個實例有4GB內(nèi)存,在應(yīng)用申請時可以按需申請足夠的實例數(shù)量來使用,對這樣的應(yīng)用需要進行分片,詳情請參考可伸縮服務(wù)架構(gòu):框架與中間件中4.4.3的內(nèi)容。這里需要注意,如果我們使用了RDB備份機制,每個實例使用4GB內(nèi)存,則我們的系統(tǒng)需要大于8GB內(nèi)存,因為RDB備份時使用了 copy-on-write 機制,需要fork出一個子進程,并且復制一份內(nèi)存,因此需要雙份的內(nèi)存存儲大小。優(yōu)秀實踐4緩存一般是用來加速數(shù)據(jù)庫的讀操作的,一般先訪問緩存后訪問數(shù)據(jù)庫,所以緩存的超時時間的設(shè)置是很重要的。筆者曾經(jīng)在一家互聯(lián)網(wǎng)公司遇到過由于運維操作失誤導致緩存超

5、時設(shè)置得較長,從而拖垮服務(wù)的線程池,最終導致服務(wù)雪崩的情況。優(yōu)秀實踐5所有的緩存實例都需要添加監(jiān)控,這是非常重要的,我們需要對慢查詢、大對象、內(nèi)存使用情況做可靠的監(jiān)控。優(yōu)秀實踐6我們不推薦多個業(yè)務(wù)共享一個緩存實例,但是由于成本控制的原因,這種情況經(jīng)常出現(xiàn),我們需要通過規(guī)范來限制各個應(yīng)用使用的key有唯一的前綴,并進行隔離設(shè)計,避免產(chǎn)生緩存互相覆蓋的問題。優(yōu)秀實踐7任何緩存的key都必須設(shè)定緩存失效時間,且失效時間不能集中在某一點,否則會導致緩存占滿內(nèi)存或者緩存雪崩。優(yōu)秀實踐8低頻訪問的數(shù)據(jù)不要放在緩存中,如我們前面所說的,我們使用緩存的主要目的是提高讀取性能。曾經(jīng)有個小伙伴設(shè)計了一套定時的批處

6、理系統(tǒng),由于批處理系統(tǒng)需要對一個大的數(shù)據(jù)模型進行計算,所以該小伙伴把這個數(shù)據(jù)模型保存在每個節(jié)點的本地緩存中,并通過消息隊列接收更新的消息來維護本地緩存中模型的實時性,但是這個模型每個月只用了一次,所以這樣使用緩存是很浪費的。既然是批處理任務(wù),就需要把任務(wù)進行分割,進行批量處理,采用分而治之、逐步計算的方法,得出最終的結(jié)果即可。優(yōu)秀實踐9緩存的數(shù)據(jù)不易過大,尤其是Redis,因為Redis使用的是單線程模型,在單個緩存key的數(shù)據(jù)過大時,會阻塞其他請求的處理。優(yōu)秀實踐10對于存儲較多value的key,盡量不要使用HGETALL等集合操作,該操作會造成請求阻塞,影響其他應(yīng)用的訪問。優(yōu)秀實踐11緩

7、存一般用于在交易系統(tǒng)中加速查詢的場景,有大量的更新數(shù)據(jù)時,尤其是批量處理時,請使用批量模式,但是這種場景較少。優(yōu)秀實踐12如果對性能的要求不是非常高,則盡量使用分布式緩存,而不要使用本地緩存,因為本地緩存在服務(wù)的各個節(jié)點之間復制,在某一時刻副本之間是不一致的,如果這個緩存代表的是開關(guān),而且分布式系統(tǒng)中的請求有可能會重復,就會導致重復的請求走到兩個節(jié)點,一個節(jié)點的開關(guān)是開,一個節(jié)點的開關(guān)是關(guān),如果請求處理沒有做到冪等,就會造成處理重復,在嚴重情況下會造成資金損失。優(yōu)秀實踐13在寫緩存時一定要寫入完全正確的數(shù)據(jù),如果緩存數(shù)據(jù)的一部分有效、一部分無效,則寧可放棄緩存,也不要把部分數(shù)據(jù)寫入緩存,否則會

8、造成空指針、程序異常等。優(yōu)秀實踐14在通常情況下,讀的順序是先緩存,后數(shù)據(jù)庫;寫的順序是先數(shù)據(jù)庫,后緩存。優(yōu)秀實踐15在使用本地緩存(如Ehcache)時,一定要嚴格控制緩存對象的個數(shù)及聲明周期。由于JVM的特性,過多的緩存對象會極大影響JVM的性能,甚至導致內(nèi)存溢出等。優(yōu)秀實踐16在使用緩存時,一定要有降級處理,尤其是對關(guān)鍵的業(yè)務(wù)環(huán)節(jié),緩存有問題或者失效時也要能回源到數(shù)據(jù)庫進行處理。三、關(guān)于常見的緩存問題的線上案例筆者在多家互聯(lián)網(wǎng)公司負責架構(gòu)方案評審和線上事故復盤,這里列舉其中的一些典型案例,供大家參考和借鑒。案例1現(xiàn)象:某應(yīng)用程序的數(shù)據(jù)庫負載瞬時升高。原因:在應(yīng)用程序中對使用的大量緩存ke

9、y設(shè)置了同一個固定的失效時間,當緩存失效時,會造成在一段時間內(nèi)同時訪問數(shù)據(jù)庫,造成數(shù)據(jù)庫的壓力較大??偨Y(jié):在使用緩存時需要進行緩存設(shè)計,要充分考慮如何避免常見的緩存穿透、緩存雪崩、緩存并發(fā)等問題,尤其是對于高并發(fā)的緩存使用,需要對key的過期時間進行隨機設(shè)置,例如,將過期時間設(shè)置為10秒+random(2),也就是將過期時間隨機設(shè)置成1012秒。案例2現(xiàn)象:導致遷移前后兩個系統(tǒng)的核心操作重復。原因:在遷移的過程中,重復的流量進入了不同的節(jié)點,由于使用了本地緩存存儲遷移開關(guān),而遷移開關(guān)在開關(guān)打開的瞬間導致各個節(jié)點的開關(guān)狀態(tài)不一致,有的是開、有的是關(guān),所以對于不同節(jié)點的流量的處理重復,一個走了開關(guān)

10、開的邏輯,一個走了開關(guān)關(guān)的邏輯。總結(jié):避免使用本地緩存來存儲遷移開關(guān),遷移開關(guān)應(yīng)該在有狀態(tài)的訂單上標記。案例3現(xiàn)象:某模塊設(shè)計使用了緩存加速數(shù)據(jù)庫的讀操作的性能,但發(fā)現(xiàn)數(shù)據(jù)庫負載并沒有明顯下降。原因:由于這個模塊的使用方查詢請求的數(shù)據(jù)在數(shù)據(jù)庫中不存在,是非法的數(shù)據(jù),所以導致緩存沒有命中,每次都穿透到數(shù)據(jù)庫,且量級較大??偨Y(jié):在使用緩存時需要進行緩存設(shè)計,要充分考慮如何避免常見的緩存穿透、緩存雪崩、緩存并發(fā)等問題,尤其是對高并發(fā)的緩存使用,需要對無效的key進行緩存,以抵擋惡意的或者無意的對無效緩存查詢的攻擊或影響。案例4現(xiàn)象:監(jiān)控系統(tǒng)報警,Redis中單個哈希鍵占用的空間巨大。原因:應(yīng)用系統(tǒng)使

11、用了哈希鍵,哈希鍵本身有過期時間,但是哈希鍵里面的每個鍵值對沒有過期時間??偨Y(jié):在設(shè)計Redis的過程中,如果有大量的鍵值對要保存,則請使用字符串鍵的數(shù)據(jù)庫類型,并對每個鍵都設(shè)置過期時間,請不要在哈希鍵內(nèi)部存儲一個沒有邊界的集合數(shù)據(jù)。實際上,無論是對緩存、內(nèi)存還是對數(shù)據(jù)庫的設(shè)計,如果使用任意一個集合的數(shù)據(jù)結(jié)構(gòu),則都要考慮為它設(shè)置最大限制,避免內(nèi)存用光,最常見的是集合溢出導致的內(nèi)存溢出的問題。案例5現(xiàn)象:某業(yè)務(wù)項目由于緩存宕機導致業(yè)務(wù)邏輯中斷,數(shù)據(jù)不一致。原因:Redis進行主備切換,導致瞬間內(nèi)應(yīng)用連接Redis異常,應(yīng)用并沒有對緩存做降級處理??偨Y(jié):對于核心業(yè)務(wù),在使用緩存時一定要有降級方案。

12、常見的降級方案是在數(shù)據(jù)庫層次預留足夠的容量,在某一部分緩存出現(xiàn)問題時,可以讓應(yīng)用暫時回源到數(shù)據(jù)庫繼續(xù)業(yè)務(wù)邏輯,而不應(yīng)該中斷業(yè)務(wù)邏輯,但是這需要嚴格的容量評估,請參考分布式服務(wù)架構(gòu):原理設(shè)計與實戰(zhàn)第3章的內(nèi)容。案例6現(xiàn)象:某應(yīng)用系統(tǒng)負載升高,響應(yīng)變慢,發(fā)現(xiàn)應(yīng)用進行頻繁GC,甚至出現(xiàn)OutOfMemroyError: GC overhead limt exceed的錯誤日志。原因:因為這個項目是個歷史項目,使用了Hibernate ORM框架,在Hibernate中開啟了二級緩存,使用了Ehcache;但是在Ehcache中沒有控制緩存對象的個數(shù),緩存對象增多,導致內(nèi)存緊張,所以進行了頻繁的GC操

13、作。總結(jié):使用本地緩存(如Ehcache、OSCache、應(yīng)用內(nèi)存)時,一定要嚴格控制緩存對象的個數(shù)及聲明周期。案例7現(xiàn)象:某個正常運行的應(yīng)用突然報警線程數(shù)過高,之后很快就出現(xiàn)了內(nèi)存溢出。原因:由于緩存連接數(shù)達到最大限制,應(yīng)用無法連接緩存,并且超時時間設(shè)置得較大,導致訪問緩存的服務(wù)都在等待緩存操作返回,由于緩存負載較高,處理不完所有的請求,但是這些服務(wù)都在等待緩存操作返回,服務(wù)這時在等待,并沒有超時,就不能降級并繼續(xù)訪問數(shù)據(jù)庫。這在BIO模式下線程池就會撐滿,使用方的線程池也都撐滿;在NIO模式下一樣會使服務(wù)的負載增加,服務(wù)響應(yīng)變慢,甚至使服務(wù)被壓垮。總結(jié):在使用遠程緩存(如Redis、Memcached)時,一定要對操作超時時間進行設(shè)置,這是非常關(guān)鍵的,一般我們設(shè)計緩存作為加速數(shù)據(jù)庫讀取的手段,也會對緩存操作做降級處理,因此推薦使用更短的緩存超時時間,如果一定要給出一個數(shù)字,則希望是100毫秒以內(nèi)。案例8現(xiàn)象:某項目使用緩存存儲業(yè)務(wù)數(shù)據(jù),上線后出現(xiàn)錯誤問題,開發(fā)人員束手無策。原因:開發(fā)人員不知道如何發(fā)現(xiàn)、排查、定位和解決緩存問題??偨Y(jié):在設(shè)計緩存

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論