背景
面對高QPS場景的業務,不得不考慮對一些數據做緩存設計,常見的緩存設計有這些:DB Proxy緩存、分布式緩存、Localcache緩存。
在考慮加緩存的背景下不考慮數據的一致性,都是瞎扯,所以我們再定義一下數據的一致性場景:強制一致性、最終一致性。本質上只要加了緩存就會破壞數據的一致性,最起碼破壞了數據的強一致性。但在不同的緩存選擇下,最終一致性的延遲效果是完全不同的。
DB Proxy緩存
DB proxy 緩存是比較簡單的一種緩存,它的拓展性和策略手段也偏少,基本上只能做某 key 某 SQL 超過一定 QPS 之后,做一些結果緩存。緩存時間可以設置個1秒、2秒、3秒,按照你的業務需求去做決定。但本質上它的策略手段因為太單一,你也沒有辦法去做一些強制的刪除或強制的更新。所以優勢就在于簡單,純配置就可以。劣勢就在于策略手段太過單一,維護熱 key 緩存的 key 的手段太過單一。而且 DB proxy 緩存一般也不能承擔太多的緩存任務,只有一些非常非常高的 key 比如說一些 key 的 QPS 超過了20K 30K 才會考慮對著一個 k 去開啟。而且是得手動針對某一個 key 去開啟,最好不要全局去開啟,避免一些不必要的問題。
分布式緩存
分布式緩存應該是最常用的,最熟悉的應該就是 Redis 它可以把 DB 的一些查詢結果做一些緩存。效果策略手段也是最好的。我們可以做一些策略化的過期時間,可以針對某一個 key 或者批量針對某一批 key 去做緩存,由業務代碼去設定,靈活性更好。缺點的話就在于它對于超高的 QPS 的 key 這個超高怎么定義呢?就從 Redis 的單 key 的承載能力去做定義。一個 key 如果超過了5000QPS 也就是5K 多流量,可以認為是熱 key 那超過10K 也就是1萬的 QPS 那基本上就靠 Redis 去緩存,也是不可靠的,會引起單分片的 CPU 問題。靠分布式緩存就不太好解決了。
Localcache緩存
對于前面提到的,如果某一個 key 超過了10K 的 QPS 就需要考慮去做 local cache 本地緩存。本地緩存優勢就在于它可以本地區直接返回結果,對吞吐量、響應的效率、速度都有非常好的支持。但它的缺陷就在于維護成本太高。因為它會消耗機器的實際內存,我們內存資源是非常寶貴的,所以一般 local CACHE 會有一個內存上限,也會有很多的淘汰算法。再一個就是使用分布式緩存的話,因為它是分布式的,你可以去做一些強制更新,緩存更新。我們常見的延遲雙刪這些技術點,都是為了保證一致性。但 local CACHE 的話,它就不太好去做這些事情了。也就是說,local CACHE 緩存的 key 它沒有辦法去全量的刪除,在它過期時間之前。這也是它的一個缺點。
選型
所以選型的話,如果一個數據是超高 QPS 超過了10K 甚至以上,并且你認為它的一致性還好,就比如是一些點贊的數值啊。直播間人數啊這些完全可以考慮去通過 local cache 去做承載,但要設置好緩存這個 key 的條件和過期時間以及淘汰策略。避免因為 local CACHE 導致整個機器的內存使用消耗太高。最常用的,最實用的應該就是分布式緩存。它可以做一些像延遲雙刪這樣的一些技術手段,去保證一致性,也可以使用一些很多的算法去策略手段去做緩存,比如把時間打散,比如說某一個 key 去設置5秒還是3秒過期,由業務代碼去決定,靈活性是最好的。DB proxy 緩存的話就比較的簡單,可以為了在發現某一個 key 對機器產生影響了之后,主動的為這個 key 開啟緩存來,算是一個運維能力去保護 DB也就是說,得你主動的去發現某 key 特別超高。然后去開啟。