【问题标题】:Memcache clustering for php sessions?用于 php 会话的 Memcache 集群?
【发布时间】:2011-04-24 00:58:28
【问题描述】:

这里有一点背景,目前我有

  • 3 个网络服务器
  • 一个数据库服务器,它还为 3 个 Web 服务器的 php 会话托管 memcache。

我有 3 个服务器上的 php 配置指向 memcache 服务器进行会话。它工作正常,直到为读取等生成大量连接,然后导致连接超时。

所以我目前正在考虑将每个 Web 服务器上的 memcache 集群化以用于会话,我唯一关心的是如何确保所有服务器上的 memcache 具有相同的会话信息。

有人将我引导至http://github.com/trs21219/Memcached-Library,因为我使用的是 codeigniter,但是我如何将我的 php 会话集中到这个上,因为 memcache 似乎是一个键值存储?提前致谢。

有人签出http://repcached.sourceforge.net/ 并且有效吗?

【问题讨论】:

    标签: php session memcached


    【解决方案1】:

    我不确定您对 memcache 的期望是否与其设计者相同。

    然而,首先,memcache 分发的工作方式与您的预期不同:没有复制存储信息的机制。正如您所注意到的,每个 memcache 实例都是一个简单的键值对存储。分发由客户端代码完成,该代码具有所有已配置的 memcache 实例的列表,并对密钥进行哈希处理以将其定向到其中一个实例。客户端可以将它存储在任何地方并在本地检索它,或者它可以多次散列它以实现冗余,但这些都不是简单的练习。

    但另一个问题是 memcache 是为合理的短期数据设计的,memcache 可以随时丢弃。这使得它非常适合缓存经常访问的数据,这些数据可能有点陈旧(比如说长达几分钟)但检索起来可能很昂贵(例如从查询中生成几乎一分钟)。

    根据我的经验,PHP 会话并不真正符合此条件。一个数据库可以轻松支持数千个 PHP 会话而流量几乎不可见,但是您需要 很多 的 memcache 存储来支持相同的数量:每个会话 50k 和 5000 个会话意味着接近 256Mb,然后是您要放入其中的所有其他数据。没有足够的存储空间,你会得到很多无法解释的注销(因为 memcache 在内存压力下会丢弃会话数据),因此会有很多恼人的用户不得不再次登录。

    【讨论】:

    • "分发由客户端代码完成" --- 实际上并非如此。阅读我的回答。
    • 是的。每个 memcached 实例都不知道也无法知道您正在运行的其他实例。选择哪个实例由客户端库完成。我知道:我查看了几个并调试了我最终选择使用的那个。 每次页面执行时都会设置池,因为这就是 PHP 的工作方式。
    • 那么你认为我最好的选择是将我的会话转移到 mysql 数据库并刚刚集群?
    • 自定义会话处理程序并不难。请参阅php.net/manual/en/function.session-set-save-handler.php 了解更多信息; cmets 似乎涵盖了所有问题。主要的两个是在第一个 session_start() 之前初始化自定义处理程序,并在关闭数据库处理程序之前强制关闭会话。
    • 您可以做两件事:1. 将wait_timeout 降低到一个实际值(MySQL 的默认值非常高)。 2.提高max_connections以适应实际流量。
    【解决方案2】:

    我们发现在大多数事情(包括会话处理)上使用 MongoDB 代替 MySQL 具有很大的优势。它更快,更小,更容易。我们保留 MySQL 以满足事务性需求,但现在其他一切都进入 Mongo。我们已将 memcache 降级为仅缓存页面和其他不重要的数据(无论是否存在),就像 smarty 一样。

    【讨论】:

      【解决方案3】:

      无需使用某些 3rd 方库来组织 memcached “集群”。

      http://ru.php.net/manual/en/memcached.addserver.php

      只需使用此功能将多个服务器添加到池中,然后数据将存储并分布在这些服务器上。用于存储/检索特定密钥数据的服务器将根据一致的密钥分配选项进行选择。

      因此,在这种情况下,您无需担心“如何确保所有服务器上的 memcache 具有相同的会话信息”

      【讨论】:

      • 但是如果我使用 php.ini 来处理我的会话,我该如何将服务器添加到池中?
      • 哦,那么对不起 - 我没有从问题中得到这个。我对您添加的“memcached-library”和“repcached”感到困惑——这就是为什么我认为您使用的不是本机支持。那么我认为最好的解决方案是使用session_set_save_handler() 实现您的自定义会话处理程序,这是琐事任务,我相信您知道这一点。然后在您的会话处理程序实现中,您当然可以使用池。
      • 当使用 session_set_save_handler() 时,php 是否仍然为每个用​​户生成一个会话 ID?我是否只需编写自定义会话处理程序以将信息写入所有 memcache 服务器?
      • 你只需实现一小部分函数并给它们session_set_save_handler()点。之后 - 您照常使用会话:session_start() 开始,$_SESSION['blabla'] = 'foobar'; 进行交互。所以使用会话的代码不需要重写。
      • 上面的那个链接已经失效了。工作于:php.net/manual/en/memcached.addserver.php
      猜你喜欢
      • 2015-04-18
      • 2015-02-28
      • 2012-11-17
      • 2011-01-01
      • 2010-11-14
      • 2014-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多