【发布时间】:2012-08-13 13:09:23
【问题描述】:
我目前在性能方面遇到了一个大问题:通过大量 I/O 生成的负载在包含大量文件 (+100.000) 的平面会话文件夹中。
sessionfiles/htdocs 文件夹位于托管存储上 - 两个单独的服务器(在负载均衡器后面)通过 nsf-mount 使用这些文件 (apache2),并同时访问相同的会话文件夹(以保持其持久性) .
不幸的是,该项目非常频繁,并且正在生成大量会话文件。即使 ans max_lifetime 为 2 小时,我们也生成了 +100.000 个会话文件,这对于 IO 节点来说已经非常重要了。
是否有可能将这些会话动态拆分为子文件夹?例如所有带有 sess_1* 的 sessionfiles 到 /tmp/sessions/1,sess_2 到 /tmp/sessions/2 等等?使用这种方法,存储/IO 节点只需处理每个文件夹约 10.000 个,这应该可以加快垃圾收集并防止 IO 负载。
我从 PHP (session.save_path) 文档中找到了这段摘录:
http://de3.php.net/manual/en/session.configuration.php#ini.session.save-path
该指令有一个可选的 N 参数,用于确定 您的会话文件将分布的目录级别数 例如,设置为 '5;/tmp' 可能最终会创建一个会话 文件和位置,如 /tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If 。为了 使用 N 您必须在使用前创建所有这些目录。一个小的 ext/session 中存在 shell 脚本来执行此操作,它被称为 mod_files.sh,带有一个名为 mod_files.bat 的 Windows 版本。另请注意 如果使用 N 并且大于 0 则自动垃圾回收 将不会执行,请参阅 php.ini 的副本以获取更多信息。 此外,如果您使用 N,请务必将 session.save_path 括在“引号”中 因为分隔符 (;) 也用于 php.ini 中的 cmets。
有没有人以前在 php 中实现过这个,并且可以为我提供一些示例 php 代码来使用这个 mod_files.sh 处理子文件夹中的会话文件?
不幸的是,它的文档记录很差......
【问题讨论】:
-
不要将会话保存在文件中。使用 Redis 或 Memcached。
-
您引用的文档非常清楚地解决了问题:“设置为'5;/tmp'”。但您可能需要考虑使用文件以外的其他内容进行会话。
-
是否必须将会话存储在文件中?因为你可以保存只是把它们放到内存缓存中。对我来说,它适用于拥有超过百万次会话的网站。
-
OZ_ 和 pomaxa:感谢您的回复! sessionfiles 是(对我而言)跨多个(在本例中为两个)服务器处理会话/持久性的最简单方法......是否可以使用 memcache 并通过 nfs 挂载将此缓存共享给所有(apache-)服务器?还是仅通过数据库?我们有一个单独的 sql 服务器,负载相当高(但“还可以”) - 真的不想将 db-server 推到极限并遇到新问题。
-
不要将数据库用于会话 - 很快自动增量字段就会溢出。如果您将使用 Redis 或 Memcached,为什么需要一些“nfs mount”?只需为此使用单独的 VPS(在您的服务器的本地网络中)。