Ubuntu的PHP会话垃圾回收cron作业需要25分钟才能运行,为什么?


13

Ubuntu设置了一个cron作业,用于查找和删除旧的PHP会话:

# Look for and purge old sessions every 30 minutes
09,39 *     * * *     root   [ -x /usr/lib/php5/maxlifetime ] \
   && [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 \
   -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) ! -execdir \
   fuser -s {} 2> /dev/null \; -delete

我的问题是,此过程需要很长时间才能运行,并且有很多磁盘IO。这是我的CPU使用率图表:

CPU使用率图

蓝绿色尖峰代表清理运行。在此期间的开始,PHP的清理作业计划为默认的09和39分钟时间。在15:00时,我从cron中删除了39分钟的时间,因此清理工作的速度是大小的两倍(您可以看到峰的宽度是原来的两倍,峰的频率是原来的两倍)。

以下是IO时间的相应图表:

IO时间

和磁盘操作:

磁盘操作

在大约14,000个活动会话处于高峰时,可以看到清理运行了整整25分钟,显然是整个周期使用了100%的一个CPU内核,似乎使用了100%的磁盘IO。为什么如此耗费资源?一个ls会话目录的/var/lib/php5只需要一秒钟的一小部分。那么,为什么要花整整25分钟来整理旧的会话?我有什么办法可以加快速度?

该设备的文件系统当前为ext4,在64位Ubuntu Precise 12.04上运行。

编辑:我怀疑负载是由于异常的过程“定影器”造成的(因为我希望简单的操作rm比我看到的性能要快得多)。我将删除热熔器的使用,然后看看会发生什么。


您的网站获得多少流量才能产生那么多会话?
迈克尔·汉普顿

Answers:


9

删除fuser应该会有所帮助。该作业fuser为找到的每个会话文件运行一个命令(检查当前是否打开了文件),在繁忙的系统上有14k个会话时,这很容易花费几分钟。这是一个Debian错误(Ubuntu基于Debian)。

除了memcached,您还可以尝试将tmpfs(内存中的文件系统)用于会话文件。像memcached一样,这会使重新启动时的会话无效(可以通过在关闭脚本中备份该目录并在启动脚本中进行还原来解决此问题),但安装起来会容易得多。但这对fuser解决问题没有帮助。


听起来像是定影器中的错误是一个较早的版本发生了分支,但是在完成时却从未收获过,这使成千上万的fuser进程处于僵尸状态,消耗了内存,从而导致服务器崩溃。我认为我正在使用的psmisc版本已解决了该问题。
thenickdude 2012年

那是另一个错误。您有一个简单的问题,即启动数千个fuser进程,所有这些进程都必须整体搜索/proc/打开的文件。
2012年

9

祝贺您拥有一个受欢迎的网站,并一直保持该网站在虚拟机上运行。

如果你真的在每天两千万次网页检视拉动,那么你会叠起来PHP会议的很多文件系统,并且他们会花费很长的时间来删除不管你是否使用fuserrm或吸尘器。

在这一点上,我建议您研究一下存储会话的替代方法:

  • 一种选择是将会话存储在中memcached。闪电般快速,但是如果服务器崩溃或重新启动,则所有会话都将丢失,所有人都将注销。
  • 您还可以将会话存储在数据库中。这将比memcached慢一些,但是数据库将是持久性的,您可以使用简单的SQL查询清除旧会话。但是,要实现此目的,您必须编写一个自定义会话处理程序

Memcached当然是一个选择,尽管它必须与我们的主要memcached实例是一个单独的池,否则会话将被随机从我们的缓存压力中逐出。我不相信删除14,000个文件应该花费25分钟。这听起来太慢了。我要等几个小时,看看简单的性能如何rm
thenickdude 2012年

在不了解您的总体体系结构的情况下,我犹豫不决地推荐一个。
迈克尔·汉普顿

您可以通过设置memcache.session_redundancy = 2来池化Memcached服务器以实现冗余。请参阅serverfault.com/questions/164350/…。如果您担心持久性,并且Redis比SQL数据库存储快得多,那么Redis是一个不错的选择。
jfountain 2014年

4

因此,此处用户建议的Memcached和数据库会话存储选项都是提高性能的不错选择,每一个都有其优点和缺点。

但是通过性能测试,我发现此会话维护的巨大性能成本几乎完全归功于fusercron作业的需求。这是恢复到Natty / Oneiric cron作业后的性能图,该作业rm不是fuser在修剪旧会话,而是在2:30进行切换。

CPU使用率

IO时间已过

磁盘操作

您可以看到,几乎完全消除了因Ubuntu的PHP会话清理而导致的定期性能下降。现在,“磁盘操作”图中的尖峰的数量级要小得多,并且可以像该图所测量的那样纤细,这显示了一个短暂的短暂中断,以前的服务器性能在25分钟内已显着降低。完全消除了额外的CPU使用率,这现在是IO绑定的工作。

(不相关的IO作业在05:00运行,而CPU作业在7:40运行,它们都在这些图形上导致它们自己的峰值)

我现在正在运行的修改后的cron作业是:

09 *     * * *     root   [ -x /usr/lib/php5/maxlifetime ] && \
   [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 \
   -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 \
   | xargs -n 200 -r -0 rm

-print0 | xargs ...不必要-您可以直接离开-delete那里。但是它将以可比的速度双向工作。
2012年

1

在进行一些会话研究时,我碰到了这篇文章。尽管接受的答案非常好(并且gc脚本已将热熔器调用删除了一段时间),但如果有人遇到类似问题,我认为值得一提的其他注意事项。

在描述的场景中,OP使用的是ext4。ext4中的目录以htree数据库格式存储文件数据-这意味着与在多个目录中分布文件相比,将多个文件保存在单个目录中的影响可忽略不计。并非所有文件系统都如此。PHP中的默认处理程序允许您对会话文件使用多个子目录(但请注意,您应检查控制进程是否递归到这些目录中-上面的cron作业不需要)。

(消除对定影器的调用后)操作的大量成本来自查看尚未过时的文件。使用(例如)单个级别的子目录,以及在每个子目录(0 /,1 // ... d /,e /,f /)中查找16个cron作业,可以消除出现的负载突增。

使用具有更快基板的自定义会话处理程序将有所帮助-但有很多选择(内存缓存,redis,mysql处理程序套接字...),这些质量在互联网上已发布,但您选择的范围取决于确切的有关您的应用程序,基础结构和技能的要求,不要忘记与默认处理程序相比,语义处理(尤其是锁定)经常存在差异。


0

有了这种流量,您就不应该在dis上进行会话。您应该使用类似memcache的东西。您所要做的就是安装php,并且无需更改任何代码。例如看

http://www.dotdeb.org/2008/08/25/storing-your-php-sessions-using-memcached/

之所以要花很长时间,是因为必须整理大量文件才能查看哪些文件可以删除。给定您在代码中设置的会话时长,Memcache可以自动使这些过期。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.