李新仁
筆者做過公司多個項目的微服務架構和改造,就微服務的緩存設計這個問題來發表一下自己的看法。
從3個層面來回答這個問題:
為什麼用緩存?
什麼場景下使用緩存?
基於緩存的架構設計點
1.為什麼用緩存
在高併發場景下,如果直接讀DB,很容易出現性能瓶頸,因此需要通過緩存來減少DB的壓力,使得大量的訪問進來能夠命中緩存,只有少量的需要讀DB。緩存基於內存,可支持的併發量遠遠大於基於硬盤的數據庫。所以對於高併發設計,緩存的設計必不可少。
2.什麼場景下使用緩存
我們都知道緩存可以提升系統響應速度,那麼一般哪些場景下需要用到緩存呢?我們可以列舉3個場景:
2.1 計數緩存
計數對於數據庫來講,是非常繁重的任務,需要查詢大量的數據,最後得出計數結果,當數據改變的時候,需要重新刷一遍,非常影響性能。
因此可以設計一個計數服務,後端對接緩存,將計數作為結果放在緩存裡面,當數據改變時,調用計數服務增加或者減少計數。計數服務可以使用Redis進行單個計數,也可以用hash表進行批量計數。
微服務中的使用場景為網關中的流量控制、配額控制等計數服務。
2.2 頻繁讀+低頻寫
比如一個網上商城,商品品類信息的更新品類相對而言是比較低的,但是幾乎所有商品相關的查詢服務都需要讀取商品的品類信息。像這種低頻寫、高頻讀的數據,比較適合放到緩存中,來提升服務性能。
2.3 較大內容的高頻讀數據
這個和2.2的主要區別是防止在緩存中的量級。比如物聯網場景中的白名單信息。接入物聯網的設備量級一般比較大,可以到萬、千萬甚至上億級別。對於這些設備的白名單控制不可能每次都讀取DB來做權限驗證。因此需要設計針對大量數據的分佈式緩存來提升服務性能。
3.基於緩存的架構設計點
基於緩存的架構設計點可以從2個方面來考慮:
3.1 分場景
要區分緩存的實際應用場景,來進行不同的緩存技術選型。對於微服務網關中的流量控制所用到的分佈式緩存,可以使用redis+本地緩存技術的方案。對於商品分類信息的存放,使用本地緩存就可以滿足需求。對於大型文件的緩存,則推薦本地文件+本地緩存的方式,配合版本管理實現。
3.2 緩存架構的高可用
引入緩存是為了解決性能瓶頸,但是實質上是引入了更多依賴。比如使用redis,如果沒有足夠的容錯機制,redis一旦掛了,則會導致服務不可用。
可以使用分片,這樣每一個緩存實例都不大,但是實例數目比較多,一方面可以實現負載均衡,防止單個實例稱為瓶頸或者熱點,另一方面如果一個實例掛了,影響面相對會小很多,高可用性大大增強。分片機制可以在客戶端實現,可以使用中間件實現,也可以使用Redis的Cluster的方式,分片的算法往往都是哈希取模,或者一致性哈希。