是否可以使用 memcache 守护进程池来更有效地共享会话?

是否可以使用 memcache 守护进程池来更有效地共享会话?

我们正在从 1 个 Web 服务器设置转变为 2 个 Web 服务器设置,我需要开始在两台负载平衡机器之间共享 PHP 会话。我们已经memcached已安装(并开始),因此,我惊喜地发现,我只需更改文件中的 3 行php.inisession.save_handlersession.save_path):

我替换了:

session.save_handler = files

和:

session.save_handler = memcache

然后在主网络服务器上我将设置session.save_path为指向本地主机:

session.save_path="tcp://localhost:11211"

并在从属网络服务器上我将设置session.save_path为指向主服务器:

session.save_path="tcp://192.168.0.1:11211"

工作完成了,我测试了它并且它有效。但是...

显然,使用 memcache 意味着会话位于 RAM 中,如果计算机重新启动或 memcache 守护程序崩溃,会话将丢失 - 我对此有点担心,但我更担心两个 Web 服务器之间的网络流量(尤其是在我们扩大规模时),因为每当有人将负载平衡到从属 Web 服务器时,他们的会话都会通过网络从主 Web 服务器获取。我想知道我是否可以定义两个,save_paths以便机器在使用网络之前查看自己的会话存储。例如:

掌握:

session.save_path="tcp://localhost:11211, tcp://192.168.0.2:11211"

奴隶:

session.save_path="tcp://localhost:11211, tcp://192.168.0.1:11211"

这是否可以成功在服务器之间共享会话并有助于提高性能?即节省 50% 时间的网络流量。或者这种技术仅适用于故障转移(例如当一个 memcache 守护进程无法访问时)?

笔记:我其实并不是专门询问 memcache 复制 - 更多的是询问 PHP memcache 客户端是否可以在池中的每个 memcache 守护进程中达到峰值,如果找到会话则返回会话,并且只有在所有存储中都找不到会话时才创建新会话。在我写这篇文章的时候,我觉得我对 PHP 的要求有点高了,哈哈...

认为:无粘性会话、循环负载平衡、LAMP 服务器。

答案1

免责声明:如果你不做大量的测试,也不向有资格的人征求第二意见,就听我的,那你就是疯了—— 我是这个游戏的新手

这个问题中提出的提高效率的想法行不通。我犯的主要错误是认为池中定义的 memcached 存储的顺序决定了某种优先级。不是这种情况。当您定义 memached 守护进程池(例如使用session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211")时,您无法知道将使用哪个存储。数据是均匀分布的,这意味着某个项目可能存储在第一个,也可能是最后一个(或者,如果 memcache 客户端配置为复制,则可能同时存储在这两个位置 - 请注意,处理复制的是客户端,memcached 服务器本身不执行此操作)。无论哪种方式都意味着使用 localhost 作为池中的第一个不会提高性能 - 命中任一存储的几率为 50%。

经过一些测试和研究,我得出结论,您可以使用 memcache 在服务器之间共享会话,但您可能不想这样做 - 它似乎并不流行,因为它的扩展性不如使用共享数据库,而且它不那么强大。我很感激对此的反馈,这样我就可以了解更多信息...

除非您有 PHP 应用程序,否则请忽略以下内容:


提示 1:如果你想使用 memcache 在 2 个服务器之间共享会话:

确保你回答是的到 ”启用 memcache 会话处理程序支持吗?“当您安装 PHP memcache 客户端时,请在/etc/php.d/memcache.ini文件中添加以下内容:

session.save_handler = memcache

在 Web 服务器 1(IP:192.168.0.1)上:

session.save_path="tcp://192.168.0.1:11211"

在 Web 服务器 2 上(IP:192.168.0.2):

session.save_path="tcp://192.168.0.1:11211"

提示 2:如果您想要使用 memcache 在 2 个服务器之间共享会话并且具有故障转移支持:

将以下内容添加到您的/etc/php.d/memcache.ini文件中:

memcache.hash_strategy = consistent
memcache.allow_failover = 1

在 Web 服务器 1(IP:192.168.0.1)上:

session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211"

在 Web 服务器 2 上(IP:192.168.0.2):

session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211"

笔记:

  • 这突出了我在原始问题中犯的另一个错误 - 我没有session.save_path在所有服务器上使用相同的。
  • 在这种情况下,“故障转移”意味着如果一个 memcache 守护程序发生故障,PHP memcache 客户端将开始使用另一个守护程序。即,任何在发生故障的存储中会话的用户都将被注销。这不是透明的故障转移。

提示 3:如果您想要使用 memcache 共享会话并且具有透明故障转移支持:

与技巧 2 相同,只是您需要在/etc/php.d/memcache.ini文件中添加以下内容:

memcache.session_redundancy=2

笔记:

  • 这会使 PHP memcache 客户端将会话写入 2 个服务器。这样您便可获得冗余(如 RAID-1),从而将写入发送到 n 个镜像,并get's在镜像上重试失败的写入。这意味着即使一个 memcache 守护程序发生故障,用户也不会丢失其会话。
  • 镜像写入是并行完成的(使用非阻塞 IO),因此速度性能不会随着镜像数量的增加而大幅下降。但是,如果您的 memcache 镜像分布在不同的机器上,网络流量将会增加。例如,使用本地主机并避免网络访问的可能性不再是 50%。
    • 显然,写入复制的延迟可能会导致检索旧数据而不是缓存未命中。问题是这对您的应用程序是否重要?您多久写入一次会话数据?
  • memcache.session_redundancy用于会话冗余,但是memcache.redundancy如果您希望它具有不同级别的冗余,还有一个 ini 选项可供您的 PHP 应用程序代码使用。
  • 您需要最新版本(仍然处于测试阶段此时)的 PHP memcache 客户端 -pecl 的 3.0.3 版本对我有用。

答案2

回复:上面的提示 3(对于其他通过谷歌偶然发现这一点的人),至少目前看来,为了使这个方法有效,你必须使用memcache.session_redundancy = N+1对于池中的 N 个服务器,至少这似乎是有效的最小阈值。(在 debian stable 上使用 php 5.3.3、pecl memcache 3.0.6、两个 memcached 服务器进行了测试。 session_redundancy=2一旦我关闭第一个服务器,它就会失败save_pathsession_redundancy=3运行正常。)

这些错误报告中似乎捕获了这一点:

答案3

除了上面显示的 php.ini 设置外,还要确保设置了以下内容:

memcache.allow_failover = 1  
memcache.hash_strategy = 'consistent'

然后,您将获得完全故障转移和客户端冗余。这种方法的缺点是,如果 memcached 在 localhost 上关闭,则在 php memcache 客户端尝试 session.save_path 中指定的池中的下一个服务器之前,始终会出现读取未命中的情况

请记住,这会影响在您的 Web 服务器上运行的 php memcache 客户端的全局设置。

答案4

memcached 不能立即进行复制,但是复制缓存(修补过的 memcached)确实如此。但是,如果您已经在使用 mysql,那么为什么不直接使用其主主复制功能并获得完整数据复制的好处呢?

C。

相关内容