36

我只看到了用于存储少量数据的会话变量的示例,例如单个用户 ID。我想知道在会话变量中保存更频繁访问的数据以避免查询数据库是否会更有效。

例如,我创建了一个用户类,该类在构建时为该用户收集定期请求的数据(他们的用户 ID、用户名、电子邮件、密码和站点特定数据的数组),并将此实例作为会话变量保存。用户初次登录后,很少需要查询数据库来获取有关用户的信息,因为它已经在内存中。

我实际上是更有效率,还是我只是因为内存使用而使系统陷入困境?

旁注 - 实际上我发现从会话中获取数据更容易,而不必担心优化我的查询和东西,所以我真的希望我不是一个白痴。

4

4 回答 4

41

首先,PHP 会话默认情况下不存储在内存中,它们存储在磁盘上,因此您写入的每个块/会话都将占用磁盘空间而不是内存(直到您使用 PHP 读取会话数据)。

是的,你可能会更有效率,但如果你想扩展,这就是为什么:


在会话中存储数据

在会话中存储一些数据是完全可以接受的。从理论上讲,没有限制(尽管我从未尝试打破它甚至推动它,只是转向更有效的解决方案)。但是,您将受到磁盘空间和 PHP 的限制memory_limit()

通常,存储在会话中的数据包括以下内容:

  • 用户名
  • 哈希
  • 注册日期
  • 其他变量(用户组 ID/密钥等)
  • 闪信
  • (不是密码!)

但是,有一个权衡。如果您的流量(和使用量)增加并且您将大量数据存储在 中$_SESSION,您很可能会开始看到问题,包括磁盘和内存使用情况。

我认为您的建议没有任何问题,但除了您列出的项目以及上述示例重叠的地方之外,还需要小心。

如果您想扩展(水平)并保留基于磁盘的会话,那么您可以选择(粘性会话或存储区域网络是一对),因为一台服务器上的磁盘不会存储与另一台服务器上的磁盘相同的会话。


会话数据位置

您可以通过调用找到 PHP 存储会话数据的位置:session_save_path()

或在 CLI 上:

php -r 'echo session_save_path(), "\n";'

您没有提到您的操作系统,但会话文件的常见位置(跨不同的操作系统类型)是:

/tmp 
/var/lib/php5/
/var/lib/php/session
c:/wamp/tmp

存储在磁盘上的会话通常具有如下所示的文件名ls -al

-rw-------  1 www www      0 2013-07-09 20:12 sess_bdsdjedmvtas5njhr5530b8rq6

值得注意的是,通常会有垃圾收集进程在特定时间段后清除死会话。它确实因操作系统而异,但它们通常存在于各种基于 LAMP 的安装中。


其他会话存储选项/方法

在您的数据库
中,会话数据通常存储在数据库中而不是本地磁盘上,这适用于具有合理流量水平的微型、小型和(取决于它是如何完成的)中型站点。

像任何其他解决方案一样,它具有优点和缺点(例如能够通过运行查询而不是从中删除会话文件来禁止/踢出用户/tmp


更大、(更高流量)站点的内存中,特别是在并发用户量很高的地方,内存可以更快地读取/写入非常频繁访问的变量或数据,而不是给数据库增加过多的负载。它可以并且仍然应该写入数据库(请参阅直写缓存),但也可以保存在内存中以进行有效访问。

一种特别有价值的技术是内存缓存。一个广泛使用的与 PHP 兼容的开源解决方案示例是Memcached,它可以在一台服务器或多个 [分布式] 上使用。我已经看到小公司和大公司都在使用它,你只需要看看谁使用它/贡献...

于 2013-07-09T21:49:27.673 回答
6

这一切都取决于服务器资源,以及您的网站/应用程序的同时用户。

你可以做一个粗略的计算,估计每个用户需要的平均会话内存,乘以同时访问者的平均数量,然后将其与服务器中 PHP 可用的内存进行比较。

此计算将帮助您以非常粗略但有用的方式估算您的场景中有多少是太多。

编辑:内存是指 RAM 和/或磁盘空间,具体取决于您的设置。

于 2013-07-09T18:02:39.910 回答
2

其他一些答案假设您的意思是使用PHP 会话来缓存数据。这是一个很好的解决方案来存储您需要从一个请求到下一个请求的临时数据。

但我想知道您的意思是使用MySQL 用户定义的变量。您可以在这些变量中存储长串数据,它们在 MySQL 服务器上的数据库线程范围内占用 RAM。但是这些用户变量在会话关闭后不会保留在内存中。它们不是存储从一个请求到下一个请求的数据的好方法。

在用户变量中存储大量数据的唯一原因是您需要在同一个数据库会话期间(这意味着在同一个 PHP 请求期间)的后续 SQL 查询中使用它们,并且您希望避免从db 服务器到您的应用程序。否则,您不妨获取结果并将其存储在 PHP 变量中。

存储临时数据的另一种解决方案是使用memcached。您可以直接存储数据,也可以使用memcached 作为 PHP 会话的后备存储

于 2013-07-09T22:54:34.010 回答
1

请记住,Web 范式鼓励无状态内存模型。也就是加载你需要渲染页面,渲染页面,释放资源。

显然有时会缓存数据,但是是的,将信息存储在会话变量中会为整个应用程序创建更多的内存使用,并且每个会话将使用您存储的任何 N 个字节。

如果您没有性能问题,请不要担心缓存。另一方面,如果您想缓存并且它只在一个服务器上供少数用户使用,请不要担心。请注意在网络场中使用会话变量的缺点(如果您使用的话)。

于 2013-07-09T17:59:38.753 回答