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

时间:2022-05-30 17:50:44

There is certain userdata read from the (MySQL) database that will be needed in subsequent page-requests, say the name of the user or some preferences.

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

Is it beneficial to store this data in the $_SESSION variable to save on database lookups?

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

We're talking (potentially) lots of users. I'd imagine storing in $_SESSION contributes to RAM usage (very-small-amount times very-many-users) while accessing the database on every page request for the same data again and again should increase disk activity.

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

3 个解决方案

#1


2  

The irony of your question is that, for most systems, once you get a large number of users, you need to find a way to get your sessions out of the default on-disk storage and into a separate persistence layer (i.e. database, in-memory cache, etc.). This is because at some point you need multiple application servers, and it is usually a lot easier not to have to maintain state on the application servers themselves.

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

A number of large systems utilize in-memory caching (memcached or similar) for session persistence, as it can provide a common persistence layer available to multiple front-end servers and doesn't require long time persistence (on-disk storage) of the data.

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

Well-designed database tables or other disk-based key-value stores can also be successfully used, though they might not be as performant as in-memory storage. However, they may be cheaper to operate depending on how much data you are expecting to store with each session key (holding large quantities of data in RAM is typically more expensive than storing on disk).

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

Understanding the size of session data (average size and maximum size), the number of concurrent sessions you expect to support, and the frequency with which the session data will need to be accessed will be important in helping you decide what solution is best for your situation.

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

#2


0  

You can use multiple storage backends for session data in PHP. Per default its saved to files. One file for one session. You can also use a database as session backend or whatever you wan't by implementing you own session save handler

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

If you want your application most scalable I would not use sessions on file system. Imagine you have a setup with mutiple web servers all serving your site as a farm. When using session on filesystem a user had to be redirected to the same server for each request because the session data is only available on that servers filesystem. If you not using sessions on filesystem it would not matter which server is being used for a request. This makes the load balancing much easier.

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

Instead of using session on filesystem I would suggest

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

  • use cookies
  • use request vars across multiple requests
  • 在多个请求中使用请求变量

or (if data is security critical)

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

  • use sessions with a database save handler. So data would be available to each webserver that reads from the database (or cluster).
  • 使用数据库保存处理程序的会话。因此,从数据库(或集群)读取的每个Web服务器都可以使用数据。

#3


0  

Using sessions has one major drawback: You cannot serve concurrent requests to the user if they all try to start the session to access data. This is because PHP locks the session once it is started by a script to prevent data from getting overwritten by another script. The usual thinking when using session data is that after your call to session_start(), the data is available in $_SESSION and will get written back to the storage after the script ends. Before this happens, you can happily read and write to the session array as you like. PHP ensures this will not destroy or overwrite data by locking it.

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

Locking the session will kill performance if you want to do a Web2.0 site with plenty of Ajax calls to the server, because every request that needs the session will be executed serially. If you can avoid using the session, it will be beneficial to user's perceived performance.

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

There are some tricks that might work around the problem:

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

  1. You can try to release the lock as soon as possible with a call to session_write_close(), but you then have to deal with not being able to write to the session after this call.
  2. 您可以尝试通过调用session_write_close()尽快释放锁定,但是您必须处理此调用后无法写入会话的问题。

  3. If you know some script calls will only read from the session, you might try to implement code that only reads the session data without calling session_start(), and avoid the lock at all.
  4. 如果您知道某些脚本调用只会从会话中读取,您可能会尝试实现仅在不调用session_start()的情况下读取会话数据的代码,并完全避免锁定。

  5. If I/O is a problem, using a Memcache server for storage might get you some more performance, but does not help you with the locking issue.
  6. 如果I / O出现问题,使用Memcache服务器进行存储可能会获得更多性能,但无法解决锁定问题。

  7. Note that the database also has this locking issue with all data it stores in any table. If your DB storage engine is not wisely chosen (like MyISAM instead of InnoDB), you'll lose more performance than you might win with avoiding sessions.
  8. 请注意,数据库也存在此锁定问题,它存储在任何表中的所有数据。如果你没有明智地选择你的数据库存储引擎(比如MyISAM而不是InnoDB),那么你将失去比你避免会话所获得的更多性能。

All these discussions are moot if you do not have any performance issues at all right now. Do whatever serves your intentions best. Whatever performance issues you'll run into later we cannot know today, and it would be premature optimization (which is the root of evil) trying to avoid them.

如果您现在没有任何性能问题,所有这些讨论都没有实际意义。尽力满足你的意图。无论你今后遇到什么性能问题,我们今天都无法知道,并且试图避免它们的过早优化(这是邪恶的根源)。

Always obey the first rule of optimization, though: Measure it, and see if a change improved it.

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

#1


2  

The irony of your question is that, for most systems, once you get a large number of users, you need to find a way to get your sessions out of the default on-disk storage and into a separate persistence layer (i.e. database, in-memory cache, etc.). This is because at some point you need multiple application servers, and it is usually a lot easier not to have to maintain state on the application servers themselves.

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

A number of large systems utilize in-memory caching (memcached or similar) for session persistence, as it can provide a common persistence layer available to multiple front-end servers and doesn't require long time persistence (on-disk storage) of the data.

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

Well-designed database tables or other disk-based key-value stores can also be successfully used, though they might not be as performant as in-memory storage. However, they may be cheaper to operate depending on how much data you are expecting to store with each session key (holding large quantities of data in RAM is typically more expensive than storing on disk).

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

Understanding the size of session data (average size and maximum size), the number of concurrent sessions you expect to support, and the frequency with which the session data will need to be accessed will be important in helping you decide what solution is best for your situation.

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

#2


0  

You can use multiple storage backends for session data in PHP. Per default its saved to files. One file for one session. You can also use a database as session backend or whatever you wan't by implementing you own session save handler

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

If you want your application most scalable I would not use sessions on file system. Imagine you have a setup with mutiple web servers all serving your site as a farm. When using session on filesystem a user had to be redirected to the same server for each request because the session data is only available on that servers filesystem. If you not using sessions on filesystem it would not matter which server is being used for a request. This makes the load balancing much easier.

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

Instead of using session on filesystem I would suggest

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

  • use cookies
  • use request vars across multiple requests
  • 在多个请求中使用请求变量

or (if data is security critical)

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

  • use sessions with a database save handler. So data would be available to each webserver that reads from the database (or cluster).
  • 使用数据库保存处理程序的会话。因此,从数据库(或集群)读取的每个Web服务器都可以使用数据。

#3


0  

Using sessions has one major drawback: You cannot serve concurrent requests to the user if they all try to start the session to access data. This is because PHP locks the session once it is started by a script to prevent data from getting overwritten by another script. The usual thinking when using session data is that after your call to session_start(), the data is available in $_SESSION and will get written back to the storage after the script ends. Before this happens, you can happily read and write to the session array as you like. PHP ensures this will not destroy or overwrite data by locking it.

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

Locking the session will kill performance if you want to do a Web2.0 site with plenty of Ajax calls to the server, because every request that needs the session will be executed serially. If you can avoid using the session, it will be beneficial to user's perceived performance.

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

There are some tricks that might work around the problem:

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

  1. You can try to release the lock as soon as possible with a call to session_write_close(), but you then have to deal with not being able to write to the session after this call.
  2. 您可以尝试通过调用session_write_close()尽快释放锁定,但是您必须处理此调用后无法写入会话的问题。

  3. If you know some script calls will only read from the session, you might try to implement code that only reads the session data without calling session_start(), and avoid the lock at all.
  4. 如果您知道某些脚本调用只会从会话中读取,您可能会尝试实现仅在不调用session_start()的情况下读取会话数据的代码,并完全避免锁定。

  5. If I/O is a problem, using a Memcache server for storage might get you some more performance, but does not help you with the locking issue.
  6. 如果I / O出现问题,使用Memcache服务器进行存储可能会获得更多性能,但无法解决锁定问题。

  7. Note that the database also has this locking issue with all data it stores in any table. If your DB storage engine is not wisely chosen (like MyISAM instead of InnoDB), you'll lose more performance than you might win with avoiding sessions.
  8. 请注意,数据库也存在此锁定问题,它存储在任何表中的所有数据。如果你没有明智地选择你的数据库存储引擎(比如MyISAM而不是InnoDB),那么你将失去比你避免会话所获得的更多性能。

All these discussions are moot if you do not have any performance issues at all right now. Do whatever serves your intentions best. Whatever performance issues you'll run into later we cannot know today, and it would be premature optimization (which is the root of evil) trying to avoid them.

如果您现在没有任何性能问题,所有这些讨论都没有实际意义。尽力满足你的意图。无论你今后遇到什么性能问题,我们今天都无法知道,并且试图避免它们的过早优化(这是邪恶的根源)。

Always obey the first rule of optimization, though: Measure it, and see if a change improved it.

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