2

在后续的页面请求中将需要从(MySQL)数据库读取的某些用户数据,例如用户名或某些首选项。

将此数据存储在 $_SESSION 变量中以节省数据库查找是否有益?

我们正在谈论(可能)很多用户。我想存储在 $_SESSION 中会增加 RAM 的使用(非常少量乘以非常多的用户),同时在每个页面请求相同数据时一次又一次地访问数据库应该会增加磁盘活动。

4

3 回答 3

2

您的问题具有讽刺意味的是,对于大多数系统,一旦您获得大量用户,您需要找到一种方法让您的会话脱离默认的磁盘存储并进入单独的持久层(即数据库,在-内存缓存等)。这是因为在某些时候您需要多个应用程序服务器,而且不必维护应用程序服务器本身的状态通常要容易得多。

许多大型系统使用内存缓存(memcached 或类似的)来进行会话持久性,因为它可以为多个前端服务器提供一个通用的持久层,并且不需要长时间的持久性(磁盘存储)。数据。

设计良好的数据库表或其他基于磁盘的键值存储也可以成功使用,尽管它们的性能可能不如内存存储。但是,根据您希望使用每个会话密钥存储多少数据(在 RAM 中保存大量数据通常比在磁盘上存储更昂贵),它们的运行成本可能会更低。

了解会话数据的大小(平均大小和最大大小)、您希望支持的并发会话数以及需要访问会话数据的频率对于帮助您确定最适合您的解决方案非常重要情况。

于 2013-01-14T22:40:35.903 回答
0

使用会话有一个主要缺点:如果用户都尝试启动会话以访问数据,则您无法为用户提供并发请求。这是因为 PHP 会在脚本启动会话后锁定会话,以防止数据被另一个脚本覆盖。使用会话数据时的通常想法是,在您调用 之后session_start(),数据可用,$_SESSION并且在脚本结束后将被写回存储。在此之前,您可以随意地对会话数组进行读写操作。PHP 确保这不会通过锁定数据来破坏或覆盖数据。

如果您想创建一个对服务器进行大量 Ajax 调用的 Web2.0 站点,锁定会话会降低性能,因为需要会话的每个请求都将连续执行。如果可以避免使用会话,将有利于用户感知性能。

有一些技巧可以解决这个问题:

  1. 您可以尝试通过调用来尽快释放锁session_write_close(),但是您必须处理在此调用之后无法写入会话的问题。
  2. 如果您知道某些脚本调用只会从会话中读取,您可能会尝试实现只读取会话数据而不调用的代码session_start(),并完全避免锁定。
  3. 如果 I/O 有问题,使用 Memcache 服务器进行存储可能会提高性能,但不会帮助您解决锁定问题。
  4. 请注意,数据库对于它存储在任何表中的所有数据也存在此锁定问题。如果您的数据库存储引擎选择不明智(例如 MyISAM 而不是 InnoDB),您将失去更多的性能,而不是避免会话可能获得的性能。

如果您现在根本没有任何性能问题,那么所有这些讨论都是没有意义的。做最符合您意图的事情。无论您以后会遇到什么性能问题,我们今天都无法知道,而试图避免它们将是过早的优化(这是邪恶的根源)。

不过,请始终遵守优化的第一条规则:测量它,看看是否有更改改进它。

于 2013-01-15T00:49:10.207 回答
0

您可以在 PHP 中为会话数据使用多个存储后端。默认情况下,它保存到文件中。一个文件一个会话。您还可以通过实现自己的会话保存处理程序将数据库用作会话后端或任何您不想要的东西

如果您希望您的应用程序最具可扩展性,我不会在文件系统上使用会话。想象一下,您有一个包含多个 Web 服务器的设置,所有这些服务器都将您的站点作为一个场来提供服务。在文件系统上使用会话时,用户必须为每个请求重定向到同一服务器,因为会话数据仅在该服务器文件系统上可用。如果您不在文件系统上使用会话,则用于请求的服务器无关紧要。这使得负载平衡更容易。

我建议不要在文件系统上使用会话

  • 使用 cookie
  • 跨多个请求使用请求变量

或(如果数据对安全至关重要)

  • 使用带有数据库保存处理程序的会话。因此,从数据库(或集群)读取数据的每个网络服务器都可以使用数据。
于 2013-01-14T22:36:12.020 回答