實戰Memcached快取系統(8)Memcached非同步實時讀寫問題的解決方案SAC

鍾超發表於2012-01-14

尊重知識,轉載請註明本文來自:程式設計藝術家Poechant的CSDN部落格 http://blog.csdn.net/poechant

伺服器後端開發系列——《實戰Memcached記憶體快取系統》》系列博文:http://blog.csdn.net/poechant/article/category/1060687


在使用Memcached時,一般實時讀寫的場景並不多見。但多是Memcached寫入後,在一定時間後才會有讀操作。但是如果應用場景,是寫入後瞬間即會有讀操作呢?似乎沒有什麼特別之處,我們依然可以這樣寫:


注:此處使用的是spymemcached客戶端。


MemcachedClient cache = new MemcachedClient(cacheServerAddr);
cache.set("key", 3600, bigData);
return cache.get("key");

如此寫入快取後,如果立刻就有其他客戶端進行讀操作,則會讀取失敗,因為set是非同步操作(async),很可能仍還沒有寫入完。


一種可行的方法,是採用同步寫操作。常用的set方法沒有這種方式,需要採用遵守Memcached的CAS(Check And Set)協議的寫操作。而這種寫操作,一般是基於讀取後得到CAS ID(類似於SVN中的版本ID),根據這個CAS ID來保證寫入時,沒有和其他寫入操作產生“寫重複”衝突。因此,在我們現在所討論的場景中,可以如下使用CAS協議:

(1)初始寫入:寫一個簡單的初始值(set,非同步操作);

(2)獲取版本:使用非同步方式獲取CAS ID;

(3)同步寫入:以同步方式寫入資料,保證在讀取前,已經寫入結束。

MemcachedClient cache = new MemcachedClient(cacheServerAddr);
cache.set(“key”, 3600, "");
long casId = cache.asyncGets("key").get().getCas();
cache.cas("key", casid, bigData);
return cache.get("key");

以這種“Set-Asyncgets-Cas”方式的快取非同步實時讀寫問題的解決方案,我們稱之為“SAC”(你一定想到了什麼⋯⋯)。


尊重知識,轉載請註明本文來自:程式設計藝術家Poechant的CSDN部落格 http://blog.csdn.net/poechant

-

相關文章