2012-10-19 37 views
0

我有一个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()步骤,而是在那里对数组进行硬编码时,所有内容都很顺利。

我完全不知道可能导致这种情况的原因,还有什么我可以尝试潜在地解决这个问题。如果您有任何想法,我会很高兴听到他们!

+0

完成我也无法找到稳定的数字来重现这一点。有时9.7k是好的,但之后5k可以解决问题。 – Eugene

+0

运行时间不一致可能由高速缓存解释。 mysql有一个查询缓存。另外,在mysql和os之间,部分文件被缓存,并且不会导致真正的磁盘查找和读取。有时候......缓存只是哗然,事情变得很慢 - 但我会想象你会看到一致性,除非服务器上的其他内容正在大量活跃地使用系统资源,这可以将内容从缓存中推出。 – goat

+0

答案是“为什么它慢?”始终是相同的:对其进行配置,例如http://stackoverflow.com/a/21189/82769 –

回答

0

为什么你需要做的“SELECT ID FROM富”,然后选择“SELECT ... FROM foo其中ID = ...” - 最大的问题在这里,这必须在一个查询