~ 700k 製品を扱う e コマース サイトのサイトマップを作成するスクリプトを作成しています。e コマース パッケージには組み込みのサイトマップ ジェネレーターが既にありましたが、大規模な製品データベース (gzip 圧縮された 50k url ファイルへのリンクを含むマスター) に対して適切にフォーマットされません。
スクリプトの実行中にメモリ管理の問題が発生し、スクリプトが php のガベージ コレクション機能を上回っているように見えます。これが私が持っているものです:
function buildSitemapFile()
{
// prep sitemap string
$content = "sitemap header info";
$max_entries_per_sitemap = 50000;
$current_batch = 0;
while (buildSitemapZip($current_batch, $content, $max_entries_per_sitemap))
{
$current_batch++;
}
// finish sitemap string, open/create file, write to it, close file
}
function buildSitemapZip($batch, &$main_content, $max_urls = 50000)
{
$file_name = *create file path string*
// add this file to the index file's content string
$main_content .= *this sitemap info*
// open and prep this batch's site map file
$handle = fopen($file_name, "w");
$content = *sitemap header info*
require_once('path_to_Product.class.php');
$product = new Product();
$group_size = 1000;
// on first time called, $group_start = 0 (0 * 50000), group_start loops till >= 50000 ((0+1) * 50000), and group_start increments by $group_size on each pass
for ($group_start = $batch * $max_urls; $group_start < ($batch + 1) * $max_urls; $group_start += $group_size)
{
// request the next group of products. the query ends with "order by id limit $group_start, $group_size"
$prods = $product->query_db_for_products($group_start, $group_size);
// loop product set adding urls to the content string
foreach($prods as $key => $prod)
{
$content .= *get info from product object to fill out the sitemap content string*
}
if (count($prods) != $group_size)
{
// end of list
$return_val = *stop looping*
break;
}
}
// complete sitemap string, write it to file, close file
// create and open gzip file, write to it, close it, erase temp sitemap file
return $return_val;
}
$group_size の値を小さくしてスクリプトを実行すると、そのような問題はないように見えますが、非常に遅くなり、(クエリの繰り返しにより) データベースへのアクセスが遅くなり始めます。
eccomerce パッケージには、そのオブジェクトに __destruct メソッドの __construct がありません。
最後にテストを実行したときは、$group_size が 10k (1k のはずでした...) で、メモリの使用量が制御不能になりました。スクリプトを停止しましたが、mem の使用量 (トップ シェル コマンドによる) が増加し続け、数時間経っても解放されていません。
問題の原因となっているスクリプトで何が起こっているのかについて何か考えはありますか?