Ubuntu的垃圾收集cron工作为PHP会话需要25分钟运行,为什么?

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核心,而整个磁盘IO似乎是100%。 为什么如此资源密集? 会话目录/var/lib/php5只需要几分之一秒。 那为什么要花25分钟来修整旧的会议呢? 有什么我可以做的,以加快这一点?

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

编辑:我怀疑负载是由于不寻常的过程“fuser”(因为我期望一个简单的rm是一个该死的视线比我看到的性能更快)。 我将删除热熔器的使用,看看会发生什么。

去除fuser应该有所帮助。 此作业为每个find的会话文件运行fuser命令(检查当前是否打开文件),在具有14k会话的繁忙系统上可能需要几分钟。 这是一个Debian的bug (Ubuntu是基于Debian的)。

除了memcached之外,你还可以尝试在会话文件中使用tmpfs(内存中的文件系统)。 就像memcached一样,这将在重启时使会话无效(这可以通过在关机脚本的某个地方备份这个目录并在启动脚本中恢复),但会更容易设置。 但是这对fuser问题没有帮助。

恭喜有一个stream行的网站,并设法保持它在虚拟机上一直运行。

如果你真的每天要浏览两百万个网页浏览量,那么你将在文件系统中堆积大量的PHP会话,无论你使用fuser还是rm ,他们都需要很长时间才能删除或吸尘器。

在这一点上,我build议你看看替代方式来存储你的会议:

  • 一个select是将会话存储在memcached 。 这是闪电般的,但如果服务器崩溃或重新启动,所有的会话都会丢失,每个人都被注销。
  • 您还可以将会话存储在数据库中。 这将比memcached慢一点,但是数据库将是持久的,你可以用一个简单的SQL查询清除旧的会话。 为了实现这个,你必须编写一个自定义的会话处理程序 。

因此,这里的用户build议的Memcached和数据库会话存储选项都是提高性能的好select,每个选项都有自己的优点和缺点。

但是通过性能testing,我发现这次会话​​维护的巨大性能成本几乎完全取决于cron工作中对fuser的要求。 这是恢复到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 

有了这种交通,你不应该把会议放在一个dis。 你应该使用类似于memcache的东西。 所有你需要做的是设置PHP,将不会需要更改代码。 看例如

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

它花费这么长时间的原因是由于它需要分类的大量文件,以查看哪些文件可以被删除。 根据您在代码中设置的会话长度,Memcache可以自动过期。