服務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...