在$ _SESSION中存储userdata与重复的DB访问

时间:2013-01-14 22:30:47

标签: php mysql session

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

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

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

3 个答案:

答案 0 :(得分:2)

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

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

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

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

答案 1 :(得分:0)

您可以在PHP中使用多个存储后端来存储会话数据。默认情况下,它保存到文件中。一个会话的一个文件。您还可以将数据库用作会话后端,或者通过实现您自己的session save handler

来使用任何数据库

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

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

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

或(如果数据是安全关键的)

  • 将会话与数据库保存处理程序一起使用。因此,从数据库(或集群)读取的每个Web服务器都可以使用数据。

答案 2 :(得分:0)

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

如果您想要对服务器进行大量Ajax调用的Web2.0站点,则锁定会话将会破坏性能,因为每个需要会话的请求都将以串行方式执行。如果您可以避免使用会话,那么对用户的感知性能将是有益的。

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

  1. 您可以尝试通过拨打session_write_close()来尽快释放锁定,但是您必须在此次通话后处理无法写入会话的问题。
  2. 如果您知道某些脚本调用只会从会话中读取,您可能会尝试实现仅在不调用session_start()的情况下读取会话数据的代码,并完全避免锁定。
  3. 如果I / O出现问题,使用Memcache服务器进行存储可能会获得更多性能,但对锁定问题没有帮助。
  4. 请注意,数据库在存储在任何表中的所有数据也存在此锁定问题。如果没有明智地选择你的数据库存储引擎(比如MyISAM而不是InnoDB),那么你将失去比避免会话所能获得的更多性能。
  5. 如果您现在没有任何性能问题,所有这些讨论都没有实际意义。尽力满足你的意图。无论你今后遇到什么样的性能问题我们今天都无法知道,并且试图避免它们的过早优化(这是邪恶的根源)。

    始终遵循优化的第一条规则:测量它,看看改变是否改进了它。