在后续的页面请求中将需要从(MySQL)数据库读取的某些用户数据,例如用户名或某些首选项。
将此数据存储在 $_SESSION 变量中以节省数据库查找是否有益?
我们正在谈论(可能)很多用户。我想存储在 $_SESSION 中会增加 RAM 的使用(非常少量乘以非常多的用户),同时在每个页面请求相同数据时一次又一次地访问数据库应该会增加磁盘活动。
您的问题具有讽刺意味的是,对于大多数系统,一旦您获得大量用户,您需要找到一种方法让您的会话脱离默认的磁盘存储并进入单独的持久层(即数据库,在-内存缓存等)。这是因为在某些时候您需要多个应用程序服务器,而且不必维护应用程序服务器本身的状态通常要容易得多。
许多大型系统使用内存缓存(memcached 或类似的)来进行会话持久性,因为它可以为多个前端服务器提供一个通用的持久层,并且不需要长时间的持久性(磁盘存储)。数据。
设计良好的数据库表或其他基于磁盘的键值存储也可以成功使用,尽管它们的性能可能不如内存存储。但是,根据您希望使用每个会话密钥存储多少数据(在 RAM 中保存大量数据通常比在磁盘上存储更昂贵),它们的运行成本可能会更低。
了解会话数据的大小(平均大小和最大大小)、您希望支持的并发会话数以及需要访问会话数据的频率对于帮助您确定最适合您的解决方案非常重要情况。
使用会话有一个主要缺点:如果用户都尝试启动会话以访问数据,则您无法为用户提供并发请求。这是因为 PHP 会在脚本启动会话后锁定会话,以防止数据被另一个脚本覆盖。使用会话数据时的通常想法是,在您调用 之后session_start()
,数据可用,$_SESSION
并且在脚本结束后将被写回存储。在此之前,您可以随意地对会话数组进行读写操作。PHP 确保这不会通过锁定数据来破坏或覆盖数据。
如果您想创建一个对服务器进行大量 Ajax 调用的 Web2.0 站点,锁定会话会降低性能,因为需要会话的每个请求都将连续执行。如果可以避免使用会话,将有利于用户感知性能。
有一些技巧可以解决这个问题:
session_write_close()
,但是您必须处理在此调用之后无法写入会话的问题。session_start()
,并完全避免锁定。如果您现在根本没有任何性能问题,那么所有这些讨论都是没有意义的。做最符合您意图的事情。无论您以后会遇到什么性能问题,我们今天都无法知道,而试图避免它们将是过早的优化(这是邪恶的根源)。
不过,请始终遵守优化的第一条规则:测量它,看看是否有更改改进它。
您可以在 PHP 中为会话数据使用多个存储后端。默认情况下,它保存到文件中。一个文件一个会话。您还可以通过实现自己的会话保存处理程序将数据库用作会话后端或任何您不想要的东西
如果您希望您的应用程序最具可扩展性,我不会在文件系统上使用会话。想象一下,您有一个包含多个 Web 服务器的设置,所有这些服务器都将您的站点作为一个场来提供服务。在文件系统上使用会话时,用户必须为每个请求重定向到同一服务器,因为会话数据仅在该服务器文件系统上可用。如果您不在文件系统上使用会话,则用于请求的服务器无关紧要。这使得负载平衡更容易。
我建议不要在文件系统上使用会话
或(如果数据对安全至关重要)