AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 422723
Accepted
thenickdude
thenickdude
Asked: 2012-08-30 18:51:39 +0800 CST2012-08-30 18:51:39 +0800 CST 2012-08-30 18:51:39 +0800 CST

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

  • 772

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,在 Ubuntu Precise 12.04 64 位上运行。

编辑:我怀疑负载是由于不寻常的过程“fuser”造成的(因为我希望一个简单rm的东西比我看到的性能更快)。我将删除 fuser 的使用,看看会发生什么。

linux
  • 5 5 个回答
  • 9045 Views

5 个回答

  • Voted
  1. Michael Hampton
    2012-08-30T19:12:06+08:002012-08-30T19:12:06+08:00

    祝贺您拥有一个受欢迎的网站,并设法让它一直在虚拟机上运行。

    如果你真的每天有 200 万的页面浏览量,那么你将在文件系统中堆积大量的 PHP 会话,无论你使用fuserorrm还是删除它们都需要很长时间吸尘器。

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

    • 一种选择是将会话存储在memcached. 这快如闪电,但如果服务器崩溃或重新启动,您的所有会话都会丢失并且每个人都会注销。
    • 您还可以将会话存储在数据库中。这会比 memcached 慢一点,但数据库是持久的,你可以用一个简单的 SQL 查询清除旧会话。不过,要实现这一点,您必须编写自定义会话处理程序。
    • 9
  2. Best Answer
    Tometzky
    2012-08-31T01:03:15+08:002012-08-31T01:03:15+08:00

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

    除了 memcached,您还可以尝试使用 tmpfs(内存中的文件系统)来存储会话文件。与 memcached 一样,这会在重启时使会话无效(这可以通过在关闭脚本中的某处备份此目录并在启动脚本中恢复来解决),但设置起来会容易得多。但这无助于fuser解决问题。

    • 9
  3. thenickdude
    2012-08-31T02:19:54+08:002012-08-31T02:19:54+08:00

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

    但是通过性能测试,我发现这个session维护的巨大性能开销几乎全部归结fuser于cron作业中的调用。这是恢复到 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
    
    • 4
  4. symcbean
    2018-05-03T14:29:44+08:002018-05-03T14:29:44+08:00

    我在对会话进行一些研究时遇到了这篇文章。虽然公认的答案非常好(并且 fuser 调用已从 gc 脚本中删除了一段时间),但我认为如果其他人遇到类似问题,还需要注意其他一些注意事项。

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

    很多操作成本(在删除对 fuser 的调用之后)来自于查看尚未过时的文件。使用(例如)单一级别的子目录,以及在每个子目录(0/、1/、...d/、e/、f/)中查找的 16 个 cron 作业将消除出现的负载颠簸。

    使用具有更快衬底的自定义会话处理程序会有所帮助 - 但有很多选择(memcache,redis,mysql 处理程序套接字......)撇开互联网上发布的质量范围不谈,你选择取决于确切关于您的应用程序、基础设施和技能的要求,不要忘记与默认处理程序相比,在处理语义(特别是锁定)方面经常存在差异。

    • 1
  5. Mike
    2012-08-30T19:11:42+08:002012-08-30T19:11:42+08:00

    对于这种流量,您不应该将会话放在磁盘上。你应该使用像 memcache 这样的东西。您所要做的就是设置 php,无需更改代码。参见示例

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

    之所以花费这么长时间,是因为它必须对大量文件进行分类以查看哪些文件可以删除。根据您在代码中设置的会话长度,内存缓存可以自动使这些过期。

    • 0

相关问题

  • Linux 主机到主机迁移

  • 如何在 Linux 机器上找到有关硬件的详细信息?

  • 如何在 Linux 下监控每个进程的网络 I/O 使用情况?

  • 在 RHEL4 上修改 CUPS 中的现有打印机设置

  • 为本地网络中的名称解析添加自定义 dns 条目

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve