2012-10-19 34 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 = ...」 - 最大的問題在這裏,這必須在一個查詢