我有一个nginx + PHP + MySQL服务器。 MySQL有一个包含作业的大型数据库。我运行的PHP脚本应该从数据库中检索所有作业并输出包含所有作业的XML源。该脚本目前以这种方式组织
$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负载完全不一致。有时可以在17秒内很好地生成9.7k的作业。在这些情况下,根据“顶部”和“显示完整的过程列表”;在get_all_job_ids()步骤中,CPU会短暂地达到100%,但随后会冷静下来,并花时间逐个检索和刷新()作业。
但在其他时候,php5-fpm和mysqld在初始id检索步骤和各个作业的循环查询期间为自己抓取所有CPU。而且,即使根据“显示完整的过程列表”;正在查询单个作业,http客户端永远不会获得任何输出,而是最终收到“504网关超时”。经过相对较长的时间(分钟)mysqld和php5-fpm恢复正常。此外,当我排除get_job_by_id()步骤而不是硬编码那里的数组时,一切都运行得很顺利。
我完全不知道可能导致这种情况的因素以及我可以尝试的其他方面可能会对此问题有所了解。如果你有任何想法,我很高兴听到他们的意见!
答案 0 :(得分:0)
为什么你需要做“SELECT id FROM foo”然后“SELECT ... FROM foo where id = ...” - 这里的BIG问题是,这必须在一个查询中完成