為什么不能用memcached存儲Session

jopen 9年前發布 | 7K 次閱讀 memcached

原文  http://www.infoq.com/cn/news/2015/01/memcached-store-session


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的更多信息,可以查看 這里



 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!