新しいアイテムをキャッシュする必要があるときに、キャッシュ内の最も古いエントリを消去することになっている Web サイトで使用するスクリプトを作成しました。私のウェブサイトは非常に大きく、500,000 枚の写真が掲載されており、キャッシュ スペースは 2 GB に設定されています。
これらの機能が問題の原因です。
function cache_tofile($fullf, $c)
{
error_reporting(0);
if(strpos($fullf, "/") === FALSE)
{
$fullf = "./".$fullf;
}
$lp = strrpos($fullf, "/");
$fp = substr($fullf, $lp + 1);
$dp = substr($fullf, 0, $lp);
$sz = strlen($c);
cache_space_make($sz);
mkdir($dp, 0755, true);
cache_space_make($sz);
if(!file_exists($fullf))
{
$h = @fopen($fullf, "w");
if(flock($h, LOCK_EX))
{
ftruncate($h, 0);
rewind($h);
$tmo = 1000;
$cc = 1;
$i = fputs($h, $c);
while($i < strlen($c) || $tmo-- > 1)
{
$c = substr($c, $i);
$i = fwrite($h, $c);
}
flock($h, LOCK_UN);
fclose($h);
}
}
error_reporting(7);
}
function cache_space_make($sz)
{
$ct = 0;
$cf = cachefolder();
clearstatcache();
$fi = shell_exec("df -i ".$cf." | tail -1 | awk -F\" \" '{print \$4}'");
if($fi < 1)
{
return;
}
if(($old = disk_free_space($cf)) === false)
{
return;
}
while($old < $sz)
{
$ct++;
if($ct > 10000)
{
error_log("Deleted over 10,000 files. Is disk screwed up?");
break;
}
$fi = shell_exec("rm \$(find ".$cf."cache -type f -printf '%T+ %p\n' | sort | head -1 | awk -F\" \" '{print \$2}');");
clearstatcache();
$old = disk_free_space($cf);
}
}
cachefolder()
を付加した正しいフォルダ名を返す関数です/
。
関数が実行されると、apache の CPU 使用率は 95% から 100% の間であり、その間、サーバー上の他のサービスへのアクセスは非常に遅くなります。また、キャッシュ ディスクの使用率が 100% であり、キャッシュをクリアするまで低下しないことに気付きました。期待していたのは、90%くらいかな。
私が cache_tofile 関数でやろうとしているのは、フォルダを作成するためにディスク領域を解放してから、キャッシュファイルを作成するためにディスク領域を解放しようとすることです。cache_space_make 関数は、解放するディスク領域の量を表す 1 つのパラメーターを取ります。
その関数では、システム コールを使用して、キャッシュ全体のディレクトリ ツリーで最も古いファイルを見つけようとしましたが、それを行うためのネイティブ php 関数を見つけることができませんでした。
キャッシュ ファイルの形式は次のとおりです。
/cacherootfolder/requestedurl
たとえば、両方の関数からhttp://www.example.com/abc/defを要求した場合、作成されるはずのフォルダーは abc であり、ファイルは def であるため、システム内のファイル全体は次のようになります。
/cacherootfolder/abc/def
http://www.example.com/111/222をリクエストすると、フォルダ 111 が作成され、ファイル 222 が作成されます。
/cacherootfolder/111/222
どちらの場合も、各ファイルには、URL に基づいてユーザーが要求したものと同じコンテンツが含まれています。(例: /cacherootfolder/111/222 には、 http://www.example.com/111/222からソースを表示したときに表示されるものと同じコンテンツが含まれています)
キャッシュ システムの目的は、すべての Web ページを最適な速度で配信することです。
私の質問は、キャッシュがいっぱいになったときにシステムがロックアップしないようにするにはどうすればよいかということです。私が提供したものよりも使用できるより良いコードはありますか?