几天前,我注意到磁盘 I/O 等待和磁盘活动下降(这很好)。然后我还注意到我的缓存已满(*)且碎片化。然后我刷新了缓存。之后,磁盘延迟和磁盘活动跳升至之前的水平(这很糟糕)。
IOtop 显示 [jbd2/sda2-8] 和 [flush-8:00] 始终位于磁盘使用率的首位。这是一台 Dell R210,硬件 RAID 1 (H200),拥有大量可用内存(总共 16 GB,其中约 8 GB 为缓冲区/缓存)。
(*) 该缓存是 PHP 的 APC 操作码缓存,可减少 PHP 脚本执行的磁盘访问。由于包含来自开发实例的文件,缓存已满且碎片化。当我注意到这一点时,我将它们过滤掉了。
问题是:为什么理论上应该减少的磁盘 I/O 却增加了?以下是来自 munin 的一些图表。缓存从 2 月 6 日到 8 日都已满。
在我按照@cyberx86 的建议注释掉 apc.mmap_file_mask 后进行了更改
答案1
如果您使用文件支持的内存映射(例如apc.mmap_file_mask=/tmp/apc.XXXXXX
),您可能会看到 I/O 增加。
尝试设置apc.mmap_file_mask
为使用共享内存(例如/apc.shm.XXXXXX
)或/dev/zero
(匿名映射内存)。保持设置未定义将默认使用匿名映射内存。
通常,mmapped 文件是一件好事:
- 与将内容完全存储在内存中相比,mmapped 文件通常需要更少的内存
- 与将某些内容保存到文件相比,mmapped 文件需要更少的磁盘 I/O(因为写入可以聚合在一起)。
但是,与纯粹将某些内容存储在内存中相比,它们确实会增加 I/O —— 当文件不断更改时,这种情况会非常严重。不使用 mmapped 文件的缺点是缺乏持久性 —— 您的缓存在重新启动后将无法继续存在,因为它仅存储在内存中。
因此,有人可能会认为,当缓存填满并稳定下来时,它正在经历最大的变化,这些变化必须不断地写入磁盘;一旦缓存满了,每个对象的 ttl 就会减慢缓存中数据被转换的速度,从而减少变化并减少磁盘写入。
答案2
几天后,我现在想用一些图表来回顾一下。这一变化大大改善了这种情况。它减少了一切,除了 IO 服务时间(我认为这是因为不再有便宜的琐碎的小型 PHP 文件读取)。
服务器负载(它已经很低了,所以我没有发现变化)。