我有一个nginx + PHP + MySQL服务器。 MySQL有一个包含作业的大型数据库。我正在运行的PHP脚本应该从数据库中检索所有作业,并输出包含所有作业的XML提要。剧本目前正在组织这样PHP脚本在生成大XML Feed时使用了很多CPU
$arr = get_all_job_ids(); //returns 18k PHP array that is fueled by SELECT `id` FROM `jobs`;
foreach ($arr as $i=>$id){
if ($i>9700){break;} //for debugging
$job = get_job_by_id($id); //PHP array generated by SELECT `title`, desc, ... FROM `jobs` WHERE `id`=$id;
$job_xml = replace_job_tags($job, $xml_template); //regular expressions
echo $job_xml;
flush();
}
服务器上没有任何人它,它是专门为只,没有其他的在其上运行的实验。首先,即使我做了诸如释放SQL结果和明确清理PHP可能没有清理的任何东西,整个内存消耗在循环中不断增加。它在flush()后会下降,但它不会回到它在迭代开始时的水平。
其次更重要的是 - 运行时间和CPU负载完全不一致。有时一个9.7k工作饲料可以在17秒内很好地生成。在这些情况下,根据“顶部”和“SHOW FULL PROCESSLIST”在get_all_job_ids()步骤中,CPU会暂时达到100%,然后平静下来并花时间逐个检索和flush()作业。
但在其他时间,php5-fpm和mysqld在初始ID检索步骤和单个作业的循环查询期间为自己获取所有CPU。另外,即使根据“SHOW FULL PROCESSLIST”个人工作正在被查询,http客户端从来没有得到任何输出,而是最终收到“504网关超时”。经过相当长的时间(分钟)mysqld和php5-fpm恢复正常。另外,当我排除get_job_by_id()步骤,而是在那里对数组进行硬编码时,所有内容都很顺利。
我完全不知道可能导致这种情况的原因,还有什么我可以尝试潜在地解决这个问题。如果您有任何想法,我会很高兴听到他们!
完成我也无法找到稳定的数字来重现这一点。有时9.7k是好的,但之后5k可以解决问题。 – Eugene
运行时间不一致可能由高速缓存解释。 mysql有一个查询缓存。另外,在mysql和os之间,部分文件被缓存,并且不会导致真正的磁盘查找和读取。有时候......缓存只是哗然,事情变得很慢 - 但我会想象你会看到一致性,除非服务器上的其他内容正在大量活跃地使用系统资源,这可以将内容从缓存中推出。 – goat
答案是“为什么它慢?”始终是相同的:对其进行配置,例如http://stackoverflow.com/a/21189/82769 –