我有一個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 –