localCache與集中式cache

使用memcache緩存數據,減少對數據庫的直接訪問,提高網站性能已經成了各大網站最基本的技術.如何更好的提高memcache緩存的利用率及命中次數會在後面的blog中單獨介紹,本文主要探討爲何及如何使用本地緩存(java localcache)提高網站性能.

localcachememcache性能比較

先來個本地緩存與memcache緩存的性能比較,有個直觀上的概念

 

Cache

請求方式

次數

時間

平均

Localcache

hashmapget請求

1

1344ms

0.00001344ms

Memcache

簡單的get請求,不做序列化

1

4437ms

0.4437ms

Db

單表查詢(有索引)

 

 

1-2ms

以上測試在開發機器.生產環境採集的數據顯示memcache的一次請求大約在0.2ms左右,如果存儲的是java object,那算上發序列化的時間在0.5ms以上.與測試數據在同一個數量級上.

通過以上數據對比,可以得知localcache的效率比memcache1萬倍以上.這個數字讓我對使用本地緩存充滿了極大的興趣.

使用localcache會帶來哪些問題

localcache有着極大的性能優勢,單機情況下,適當使用localcache會使程序的效率得到很大的提升.但在集羣環境下localcache就存在很多問題了,主要體現在多個jvm之間cache的同步問題.

有很多框架在這上面做了很多工作,比如ehcache ,主要是通過cache複製(copyinvalidate)來解決,大概的思路是使用消息多播機制,當一個jvm中的數據做了更新操作後,首先更新本jvm內的localcache,然後廣播消息,其他jvm接收到消息後更新自己的localcache. 但這種機制可能帶來併發操作時出現髒數據的問題,具體見Potential Issues with Replicated Caching.

其他cache產品也遇到類似的問題,不再一一介紹.

那有沒有很好的方法來解決localcache的同步問題,從而可以放心的品嚐localcache這塊"甜餅"?

這個問題我也很糾結,通過多種方案的組合及補償機制似乎可以實現一個完美的方案.但也註定成爲了一個複雜的方案.類似的方案可以有如下幾種:

1.localcache作爲一級緩存,通過廣播的方式同步緩存,同時設置緩存過期時間,以達到數據同步和出現髒數據後自動修復的功能.

2.localcache作爲一級緩存,數據更新後發送異步消息(MQ),其餘localcache訂閱異步消息,並根據消息來同步緩存.

3.localcache作爲一級緩存,memcache中存放緩存變更的信息,定時任務定時獲取memcache的信息,並決定是否更新localcache.

4.localcache作爲一級緩存,每次從memcache中獲取數據更改的標記位,如果標記發生變化,更新localcache

以上的這些實現方案,都在一定程度上加大了架構的複雜性,localcache中數據出現髒數據時,排查問題及清理數據都會變得複雜.

他人經驗之談

1.sohu早期使用廣播的方式(jgroup)同步localcache,結果經常會出現髒數據的問題,在後來的架構設計上乾脆摒棄了localcache(即使使用,也不再作數據同步),全部使用memcache.

2.taobao在生產環境也很少使用localcache同步,對於非敏感性數據,只是通過簡單的過期策略,來保證數據的一致性.

總結

集羣環境下對於敏感性要求不高的數據可以使用localcache,只配置簡單的失效機制來保證數據的一致性.

對敏感性高的數據直接使用集中式緩存,減低複雜度.

複雜方案看似完美的解決了問題,實際上性能和穩定性卻很可能大打折扣.

感謝William 、放翁提出的寶貴建議。

發佈了22 篇原創文章 · 獲贊 1 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章