是否建议将 PHP 会话存储在 MemCache 中?

Posted

技术标签:

【中文标题】是否建议将 PHP 会话存储在 MemCache 中?【英文标题】:Is it recommended to store PHP Sessions in MemCache? 【发布时间】:2012-12-06 10:19:36 【问题描述】:

我正在使用负载均衡器后面的几个 Web 服务器,我可以启用粘性会话以将用户保留到一个特定的 Web 服务器 - 这会起作用。

我一直在阅读有关 php Sessions 和 MemCache 的信息。我必须说我读到的内容有点令人困惑,因为有些页面说这是个好主意,而另一些则相反。

问题:

    是否可以在内存缓存中保留 php 会话? 使用粘性会话而不是内存缓存更好吗? memcache 中的 php 会话有什么问题 - 注意:我可以获得足够的缓存(亚马逊因此可扩展)。

【问题讨论】:

第三个选项是将会话存储在数据库中。您可以使用 session_set_save_handler() 方法:php.net/manual/en/function.session-set-save-handler.php。您将获得更容易扩展的性能优势。 永远不要使用数据库作为会话处理程序。这是来自@Jabari 的非常糟糕的建议。实际上,您应该将数据库的使用降至最低以节省负载和内存。这就是为什么我们有 memcached 和 apc 之类的东西。我使用 memcached 进行频繁的读/写,如会话,使用 apc 存储相当恒定的内容,如文章和表单中选择框的选项。然后将数据库用作备用数据库,并在必要时重新初始化 memcache 和 apc... @Jette 请记住,该评论早在 2012 年。是的,memcache 和/或 Redis 是更好的选择。 我在 2012 年之前就尝试过,结果是一场灾难。 @Jabari,我无法链接到将数据库用作会话处理程序的实现。我们简单地尝试了一下,然后切换到 memcache。数据库上的读/写负载太重了。可能当时使用的数据库服务器容量不够大,但是使用 mysql 作为 session handler 和使用其他东西的区别是如此明显,以至于我再也不会这样做了。 【参考方案1】:

1:是的。我强烈建议将 PHP 会话存储在 Memcached 中。原因如下:

Memcached 非常适合存储数据库和文件系统经常访问的小块数据。

Memcached 专为会话而设计。它最初是 livejournal.com 的首席开发人员的创意,后来也用于缓存用户帖子的内容。好处是立竿见影的:大部分动作都发生在记忆中。页面加载时间大大缩短。

谢天谢地,PHP 和 Apache 有一个简单的实现来处理与 Memcached 的会话。只需几个 shell 命令即可安装

Debian 示例:

sudo apt-get -t stable install php7.4-memcached

将您的 php.ini 设置更改为类似于:

(取自https://www.php.net/manual/en/memcached.sessions.php)

 session.save_handler = memcached
 ; change server:port to fit your needs...
 session.save_path = "localhost:11211"

关键是session.save_path

它将不再指向您服务器上的相对文件路径。 提到了 APC - APC 用于缓存程序使用的 .php 文件。 APC 和 Memcached 将显着减少 IO,让 Apache/nginx 更快地释放服务器资源,例如图像。

2:

3: 使用 Memcached 的根本缺点是数据易波动

会话数据在 Memcached 中不持久。因此,当服务器崩溃时,内存中的所有数据都会丢失。每个人都必须重新登录。

然后你有内存消耗......

记住:会话存储在内存中。如果您的网站处理大量并发用户,您可能需要支付一些额外的钱来获得更大的内存分配。

【讨论】:

我们广泛使用它,而 Memcached 是一种轻松的方式。由于答案中的明显原因,我什至不建议您使用文件系统存储。 自我发布此答案以来已经有几年了,值得注意的是,有一个强大的扩展会话替代方案:Redis。 PHP 有一个很棒的插件解决方案,称为 Predis 库,实现只需几分钟,几乎和上面的 Memcached 解决方案一样简单。 我同意可怕的代码,这取决于这里的可用性 Redis 可能是一个更好的解决方案。但这取决于正在使用的软件堆栈恕我直言。对我们来说,由于我们的应用程序中 PHP 的内置会话变量,我们倾向于同时使用 Memcache 和 Redis。 Redis 用作产品密钥查找。它是通过设计、遗留支持和组织来完成的。 Redis 可以很容易地代替所有东西。 请注意,答案是提供有关 memcacheD 的信息,但 php.ini 配置仅适用于 memcache 另外请记住,有一个警告:会话锁定不适用于 memcached,这意味着您可能会遇到竞争条件..【参考方案2】:

1。是的,可以将 PHP 会话保存在 memcached 中。

memcache 扩展甚至附带一个会话处理程序,只需很少的配置即可启动和运行。 http://php.net/manual/en/memcached.sessions.php

2。内存缓存/粘性会话

我真的不知道哪个“更好”。我觉得这将是那些“视情况而定”的答案之一。这可能取决于您进行负载平衡的原因。如果少量用户导致每个负载很大,或者如果是大量用户导致每个负载很小。

3。 Memcache 的缺点

使用 memcache 进行会话存储可能有 2 个主要缺点。

首先,它是易变的。这意味着,如果您的某个 memcached 实例重新启动/崩溃等,则存储在该实例中的任何会话都将丢失。如果他们使用传统的基于文件的会话,当服务器返回时,他们仍然存在。

其次,可能更相关,memcached 不保证持久性,它只是一个缓存。可以随时出于任何原因从 memcached 中清除数据。而实际上,应该清除数据的唯一原因是缓存是否接近其大小限制。最近最少访问的数据将被驱逐。同样,这可能不是问题,因为如果用户的会话过时,用户可能已经离开,但这取决于您的需求。

【讨论】:

你确定是 3 吗?如果您重新启动内存缓存,我认为您不会从内存缓存中丢失会话 是的,我确定。至少在其正常配置中。 Memcached 仅将数据存储在内存 (RAM) 中。如果重新启动计算机,甚至只是重新启动服务,它都会丢失。它被设计为缓存,而不是持久存储。如果您需要持久性,其他选项,如 memcacheDB、redis 或许多其他更传统的数据库(例如 MySQL)也可用于会话(在此处查看答案***.com/questions/1316852/… - 这是一个 Java 问题,但很多(大多数/全部?)答案仍然适用) 通过任何合理的配置,您的会话可以持续到内存缓存重启。您需要定期写入数据库中的会话,以及每个 X 页面加载或类似内容。然后会话保持最新。如果您的会话加载的数据非常多,这可能不起作用。 本机 Memcache 服务器没有实现任何“直写”或持久性。重新启动服务器将清除所有数据。积极的一面:PHP 每次回写会话时,都会使用 session_max_lifetime 作为 Memcache 的过期时间,因此 Memcache 会自动清理过期的会话,无需任何额外工作。将其与使用随机触发会话文件清理的基于文件的默认会话存储进行比较。【参考方案3】:

如果要使用“memcacheD”扩展而不是“memcache”(有两种不同的扩展)进行会话控制,请注意修改php.ini

Google 的大多数网络资源都基于 memcache,因为它的版本比 memcacheD 更早。他们会说:

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

但是当涉及到 memcacheD 时它是无效的。

你应该像这样修改 php.ini:

session.save_handler = memcached 
session.save_path = "localhost:11211" 

没有协议标识符。

发件人:http://php.net/manual/en/memcached.sessions.php#99646

【讨论】:

【参考方案4】:

在我看来,不建议将会话存储在 Memcached 中。如果会话消失,通常用户会注销,如果缓存的一部分消失或由于硬件崩溃,它不会给用户带来明显的痛苦.根据 memcached 网站,“memcached 是一种高性能的分布式内存对象缓存系统,本质上是通用的,但旨在通过减轻数据库负载来加速动态 Web 应用程序。”因此,在开发应用程序时,请记住,一旦在 Memcached 服务器中找不到数据,您必须有一个备用机制来检索数据。

【讨论】:

以上是关于是否建议将 PHP 会话存储在 MemCache 中?的主要内容,如果未能解决你的问题,请参考以下文章

Memcache--02 源码安装nginx,php

如何检查是不是为 PHP 安装了 memcache 或 memcached?

会话 VS 文件 VS Memcache 用于 PHP 中的缓存?

memcache 可以横向扩展吗?

memcache、memcached和redis的区别

memcache