如下內容轉自:http://www.infoq.com/cn/news/2015/01/memcached-store-sessionhtml
-------------------------分割線-----------------------------------------------算法
Memcached建立者Dormando很早就寫過兩篇文章[1][2],告誡開發人員不要用memcached存儲Session。他在第一篇文章中給出的理由大體是說,若是用memcached存儲Session,那麼當memcached集羣發生故障(好比內存溢出)或者維護(好比升級、增長或減小服務器)時,用戶會沒法登陸,或者被踢掉線。而在第二篇文章中,他則指出,memcached的回收機制可能會致使用戶平白無故地掉線。
Titas Norkūnas是DevOps諮詢服務提供商Bear Mountain的聯合創始人。因爲看到Ruby/Rails社區忽略了Dormando那兩篇文章所指出的問題,因此他近日撰文對此進行了進一步的闡述。他認爲問題的根本在於,memcached是一個設計用於緩存數據而不是存儲數據的系統,所以不該該用於存儲Session。
對於Dormando的那兩篇文章,他認爲第一篇文章給出的緣由很容易理解,而人們常常會對第二篇文章給出的緣由認識不足。所以他對這個緣由進行了詳細地闡述:
Memcached使用「最近最少使用(LRU)」算法回收緩存。但memcached的LRU算法針對每一個slab類執行,而不是針對總體。
這意味着,若是全部Session的大小大體相同,那麼它們會分紅兩三個slab類。全部其它大小大體相同的數據也會放入同一些slab,與Session爭用存儲空間。一旦slab滿了,即便更大的slab中還有空間,數據也會被回收,而不是放入更大的slab中……在特定的slab中,Session最老的用戶將會掉線。用戶將會開始隨機掉線,而最糟糕的是,你極可能甚至都不會注意到它,直至用戶開始抱怨……
另外,Norkūnas提到,若是Session中增長了新數據,那麼Session變大也可能會致使掉線問題出現。
有人提出將Session和其它數據分別使用單獨的memcached緩存。不過,因爲memcached的LRU算法是局部的,那種方式不只致使內存使用率不高,並且也沒法消除用戶由於Session回收而出現隨機掉線的風險。
若是讀者很是但願藉助memcached提升Session讀取速度,那麼能夠借鑑Norkūnas提出的memcached+RDBMS(在有些狀況下,NoSQL也能夠)的模式:
當用戶登陸時,將Session 「set」到memcached,並寫入數據庫;
在Session中增長一個字段,標識Session最後寫入數據庫的時間;
每一個頁面加載的時候,優先從memcached讀取Session,其次從數據庫讀取;
每加載N頁或者Y分鐘後,再次將Session寫入數據庫;
從數據庫中獲取過時Session,優先從memcached中獲取最新數據。
關於memcached的更多信息,能夠查看這裏[3]。
感謝郭蕾對本文的審校。
[1]:http://www.dormando.me/articles/memcached_sessions/數據庫
[2]:http://dormando.livejournal.com/495593.html緩存
[3]:http://work.tinou.com/2011/04/memcached-for-dummies.html服務器
-----------------------------分割線---------------------session
PS:LRU算法和Memcache有空在整理下memcached