会话变量:多少数据太多了?

时间:2013-07-09 17:53:39

标签: php mysql session-variables

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

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

我实际上是否更有效率,或者我只是在内存使用情况下陷入困境?

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

4 个答案:

答案 0 :(得分:32)

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

是的,你可能会更有效率,但如果你想扩展则不是,这就是原因:


在会话中存储数据

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

通常,会话中存储的数据包括:

  • 用户名
  • 散列
  • 注册日期
  • 其他变量(用户组ID /密钥等)
  • Flash消息
  • (不是密码!)

然而,有一个权衡。如果您的流量(和使用量)增加并且您在$_SESSION中存储了大量数据,则很可能会在磁盘和内存使用方面开始出现问题。

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

如果您想扩展(水平)并保留基于磁盘的会话,那么您有一些选项(sticky sessions或存储区域网络是一对),因为一台服务器上的磁盘不会存储与另一台服务器上的磁盘。


会话数据位置

您可以通过调用session_save_path()

找到PHP存储会话数据的位置

或在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删除会话文件)

内存
对于较大的(较高流量)站点,特别是并发用户量较高的站点,对于非常频繁访问的变量或数据,内存更快地读/写,而不是为数据库添加过度负载。它可以而且应该仍然写入数据库(参见write-through caching),但也可以保存在内存中以便有效访问。

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

答案 1 :(得分:5)

这完全取决于服务器资源以及您网站/应用的同时用户。

您可以通过估算每个用户需要的平均会话内存,将其乘以平均同时访问者数量,并将其与服务器中可用于PHP的内存进行比较来进行粗略计算。

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

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

答案 2 :(得分:2)

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

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

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

存储短暂数据的另一种解决方案是使用memcached。您可以直接存储数据,也可以使用memcached as a backing store for your PHP session

答案 3 :(得分:1)

尽量记住网络范例鼓励无状态记忆模型。也就是说,加载渲染页面,渲染页面和释放资源所需的内容。

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

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