J2Cache 和普通緩存框架有何不同,它解決了什麼問題? 原 薦

不少人看到 J2Cache 第一眼時,會認爲這就是一個普普通通的緩存框架,和例如 Ehcache、Caffeine 、Spring Cache 之類的項目沒什麼區別,無非是造了一個新的輪子而已。事實上完全不是一回事!

目前緩存的解決方案一般有兩種:

  • 內存緩存(如 Ehcache) —— 速度快,進程內可用
  • 集中式緩存(如 Redis)—— 可同時爲多節點提供服務

現有的緩存框架已經非常成熟而且優秀,J2Cache 無心造一個新的輪子,它要解決的幾個問題如下:

  1. 使用內存緩存時,一旦應用重啓後,由於緩存數據丟失,緩存雪崩,給數據庫造成巨大壓力,導致應用堵塞
  2. 使用內存緩存時,多個應用節點無法共享緩存數據
  3. 使用集中式緩存,由於大量的數據通過緩存獲取,導致緩存服務的數據吞吐量太大,帶寬跑滿。現象就是 Redis 服務負載不高,但是由於機器網卡帶寬跑滿,導致數據讀取非常慢

在遭遇問題1、2 時,很多人自然而然會想到使用 Redis 來緩存數據,因此就難以避免的導致了問題3的發生。

當發生問題 3 時,又有很多人想到 Redis 的集羣,通過集羣來降低緩存服務的壓力,特別是帶寬壓力。

但其實,這個時候的 Redis 上的數據量並不一定大,僅僅是數據的吞吐量大而已。

咱們假設這樣一個場景:

有這麼一個網站,某個頁面每天的訪問量是 1000萬,每個頁面從緩存讀取的數據是 50K。緩存數據存放在一個 Redis 服務,機器使用千兆網卡。那麼這個 Redis 一天要承受 500G 的數據流,相當於平均每秒鐘是 5.78M 的數據。而網站一般都會有高峯期和低峯期,兩個時間流量的差異可能是百倍以上。我們假設高峯期每秒要承受的流量比平均值高 50 倍,也就是說高峯期 Redis 服務每秒要傳輸超過 250 兆的數據。請注意這個 250 兆的單位是 byte,而千兆網卡的單位是“bit” ,你懂了嗎? 這已經遠遠超過 Redis 服務的網卡帶寬。

所以如果你能發現這樣的問題,一般你會這麼做:

  1. 升級到萬兆網卡  —— 這個有多麻煩,相信很多人知道,特別是一些雲主機根本沒有萬兆網卡給你使用(有些運維工程師會給這樣的建議)
  2. 多個 Redis 搭建集羣,將流量分攤多多臺機器上

如果你採用第2種方法來解決上述的場景中碰到的問題,那麼你最好準備 5 個 Redis 服務來支撐。在緩存服務這塊成本直接攀升了 5 倍。你有錢當然沒任何問題,但是結構就變得非常複雜了,而且可能你緩存的數據量其實不大,1000 萬高頻次的緩存讀寫 Redis 也能輕鬆應付,可是因爲帶寬的問題,你不得不付出 5 倍的成本。

那麼 J2Cache 的用武之處就在這裏。

如果我們不用每次頁面訪問的時候都去 Redis 讀取數據,那麼 Redis 上的數據流量至少降低 1000 倍甚至更多,以至於一臺 Redis 可以輕鬆應付。

J2Cache 其實不是一個緩存框架,它是一個緩存框架的橋樑。它利用現有優秀的內存緩存框架作爲一級緩存,而把 Redis 作爲二級緩存。所有數據的讀取先從一級緩存中讀取,不存在時再從二級緩存讀取,這樣來確保對二級緩存 Redis 的訪問次數降到最低。

有人會質疑說,那豈不是應用節點的內存佔用要飆升?我的答案是 —— 現在服務器的內存都是幾十 G 打底,多則百 G 數百 G,這點點的內存消耗完全不在話下。其次一級緩存框架可以通過配置來控制在內存中存儲的數據量,所以不用擔心內存溢出的問題。

剩下的另外一個問題就是,當緩存數據更新的時候,怎麼確保每個節點內存中的數據是一致的。而這一點算你問到點子上了,這恰恰是 J2Cache 的核心所在。

J2Cache 目前提供兩種節點間數據同步的方案 —— Redis Pub/Sub 和 JGroups 。當某個節點的緩存數據需要更新時,J2Cache 會通過 Redis 的消息訂閱機制或者是 JGroups 的組播來通知集羣內其他節點。當其他節點收到緩存數據更新的通知時,它會清掉自己內存裏的數據,然後重新從 Redis 中讀取最新數據。

這就完成了 J2Cache 緩存數據讀寫的閉環。

爲什麼不用 Ehcache 的集羣方案?

對 Ehcache 比較熟悉的人還會問的就是這個問題,Ehcache 本身是提供集羣模式的,可以在多個節點同步緩存數據。但是 Ehcache 的做法是將整個緩存數據在節點間進行傳輸。如咱們前面的說的,一個頁面需要讀取 50K 的緩存數據,當這 50K 的緩存數據有更新時,那麼需要在幾個節點間傳遞整個 50K 的數據。這也會造成應用節點間大量的數據傳輸,這個情況完全不可控。

補充:當然這個單個數據傳輸量本身並不比使用 J2Cache 多,但是 ehcache 利用 jgroups 來同步數據的做法,在實際測試過程中發現可靠性還是略低,而且 jgroups 的同步數據在雲主機上無法使用。

而 J2Cache 傳輸的僅僅是緩存的 key 而已,因此相比 Ehcache 的集羣模式,J2Cache 要傳輸的數據極其小,對節點間的數據通信完全不會產生大的影響。

--------

更詳細的介紹請參考 https://gitee.com/ld/J2Cache 項目的 Readme ,以及 Readme 裏的視頻講解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章