为什么不能用 memcached 存储 Session?

发布于 2024-10-28 06:52:34 字数 1970 浏览 4 评论 0

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 中获取最新数据。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

饭团

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

金兰素衣

文章 0 评论 0

ゃ人海孤独症

文章 0 评论 0

一枫情书

文章 0 评论 0

清晰传感

文章 0 评论 0

mb_XvqQsWhl

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文