快取設計 快取誤用

2021-10-24 07:45:11 字數 2125 閱讀 3753

服務1和服務2約定好key和value,通過快取傳遞資料;服務1將資料寫入快取,服務2從快取讀取資料,達到兩個服務通訊的目的。

存在問題

資料管道,資料通知場景,mq更加合適:思想是讓專業的軟體幹專業的事情,nginx做反向**,db做固話,cache做快取,mq做通道

多個服務關聯同乙個快取例項,會導致服務耦合:

a. 兩個服務要約定好key的格式,value的格式,要保證兩個服務的redis的ip和相關配置一致,如果一方改動,另外一方也要改動,所以耦合了。

b. 約定好同乙個key,可能會產生資料覆蓋,導致資料不一致;或者會導致刪除key的時候誤刪另外乙個服務的某些key。

c. 不同服務的業務模式、資料量、併發量不一樣,會導致兩個服務之間相互影響,例如service-a資料量大,占用了cache的絕大部分記憶體,會導致service-b的熱資料全部被擠出cache,導致cache失效;又例如service-a併發量高,占用了cache的絕大部分連線,會導致service-b拿不到cache的連線,從而服務異常。

常規快取玩法,如下圖所示:服務先讀快取,快取命中則返回,快取不命中,則讀資料庫

存在問題:如果redis這個單點掛掉了,那麼所有的請求都落到db層,如果db層扛不住,那麼系統就徹底不可用了,這個就叫雪崩。

所以上面的設計一定是做過容量評估後,可以容忍redis這個單點掛掉的,才能執行這個方案。如果說可能會有雪崩的可能(即redis掛掉,db必然扛不住),那麼要實施如下兩個方案中的任意乙個方案。

方案一:快取高可用:冗餘 + 自動故障轉移

如上圖,如果m例項掛了,可以流量自動轉移到s。

方案二:快取水平切分

如上圖,使用快取水平切分(推薦使用一致性雜湊演算法進行水平切分),乙個快取例項掛掉後,不至於所有的流量都壓到資料庫上。

如上圖:

服務提供方使用快取,向呼叫方遮蔽底層的複雜性,這個是沒問題的

服務呼叫方,也快取乙份資料,先讀自己的快取,再決定是否呼叫服務

存在問題

呼叫方需要關注資料獲取的複雜性,屬於耦合的問題

服務層db修改,淘汰redis快取,難以通知呼叫方淘汰cache,從而導致資料不一致。

如果服務通過mq的方式通知呼叫方,這個設計更坑,下游服務要依賴上游的呼叫方,這個就違反了分層架構設計裡面的不能反向依賴原則。

如上圖,服務a和服務b公用乙個快取例項(不是通過這個快取例項交換資料)

存在問題

可能導致key衝突,彼此沖掉對方的資料

不同服務對應的資料量,吞吐量不一樣,公共乙個例項會導致乙個服務把另乙個服務的熱資料擠出去,或者一方誤用了redis導致另一服務不可用。

共用乙個例項,會導致服務之間耦合,與微服務架構中的「資料庫,快取私有」的設計原則相悖。

如上圖:各個府服務私有化自己的資料儲存,對上游遮蔽底層的複雜性

服務於服務之間不要通過快取傳遞資料,如果傳遞資料,請用mq,專業的軟體幹專業的事情。

容量評估的時候,如果快取掛掉,可能會導致雪崩,此時要麼做快取高可用,要麼做快取的水平切分

呼叫方不宜再單獨使用快取儲存服務底層的資料,容易出現資料不一致,以及反向依賴。

不同服務,快取例項要做垂直拆分。

Redis快取設計之快取穿透 快取雪崩

提高系統響應速度,加速讀寫,redis將數全都存放在記憶體中,響應速度更快。降低了後台的負載,減少了對後端的直接訪問 資料一致性問題,快取層的資料與儲存層的資料可能存在不一致的問題 維護複雜度高了,加入快取後要同時處理快取曾和持久層的 邏輯 快取穿透就是指查詢乙個根本不存在的資料,導致很多請求直接穿...

簡單快取設計

在專案開發中,快取起到至關重要的作用,它能加快程式執行的速度,提高程式效能。按照快取是否備份到磁碟中,可將快取分為兩種 只在記憶體中執行,斷電後消失 與磁碟中的檔案進行交換,下次啟動時能從檔案中恢復。筆者在實際中用到了幾種快取,下面簡單總結。1,堆疊式快取。這種快取適合儲存大小一致的資料塊。初始化時...

業務快取設計

對於優化 速度,快取有 cdn,js及靜態資源檔案快取。資料庫快取,資料對映層快取 mybatis 以及業務層快取。快取能提高訪問速度,但也會造成 邏輯複雜度的增加。通常快取對於非實時性的可以選擇失效時間,對於實時性要求較高的則最好採用事件式更新。使用快取時,一致性很重要,這樣就涉及到不能用類似eh...