PHP開発慣行では、APCU拡張機能を使用して、リクエスト間でデータを共有します。ただし、PHPの共有メモリメカニズムは実行モデル(特にFPMまたはApacheのマルチプロセスモード)によって制限されるため、開発者はしばしば「マルチプロセス共有キャッシュ」を誤解しています。この記事では、 APCU_Entry関数を通じて典型的なマルチプロセスプログラムでAPCUキャッシュの共有使用を実装する方法について説明します。
APCU(代替PHPキャッシュユーザー)は、共有メモリに基づいてデータキャッシュを実装するPHPのユーザーキャッシュモジュールです。 CLIモードとWebモードに適していますが、1つの制限があります。マルチプロセスモデルでは、各PHPプロセス間で可変空間が共有されず、APCU共有はメモリマッピングに依存します。
これは、PHPが同じAPCUメモリ領域を使用する限り、すべてのプロセスがこの共有メモリのキャッシュデータにアクセスできることを意味します。可変スコープは分離されていますが、キャッシュは分離されていません。
APCU_Entryは、キャッシュアイテムを取得または生成するためにPHP 5.5+で導入された関数です。その典型的な使用法は次のとおりです。
$value = apcu_entry('cache_key', function() {
return some_expensive_function();
});
その実用的な原則は次のとおりです。
cache_keyが存在するかどうかを確認します。
存在する場合は、直接返します。
存在しない場合は、閉鎖内の関数を実行し、結果をキャッシュし、返します。
この「レイジーコンピューティング +キャッシュ」戦略は、複数のプロセスでのリソース共有要件に非常に適しています。
PHPのPCNTL_FORKを例として、マルチプロセスシナリオをシミュレートして、キャッシュが共有されているかどうかを確認します。
<?php
if (!extension_loaded('apcu')) {
die("APCu 拡張機能が有効になっていません\n");
}
apcu_clear_cache();
$pid = pcntl_fork();
if ($pid == -1) {
die("子プロセスを作成できません\n");
} elseif ($pid === 0) {
// サブプロセス
$data = apcu_entry('shared_key', function () {
echo "サブプロセス:キャッシュミス,データを生成します\n";
return 'サブプロセス写入的数据 ' . time();
});
echo "サブプロセス读取缓存:$data\n";
} else {
// 親プロセス
sleep(1); // 等待サブプロセス先执行
$data = apcu_entry('shared_key', function () {
echo "親プロセス:キャッシュミス,データを生成します\n";
return '親プロセス写入的数据 ' . time();
});
echo "親プロセス读取缓存:$data\n";
}
通常、あなたは見るでしょう:
サブプロセス:キャッシュミス,データを生成します
サブプロセス读取缓存:サブプロセス写入的数据 1715600000
親プロセス读取缓存:サブプロセス写入的数据 1715600000
これは、APCUのキャッシュされたコンテンツが実際に親と子のプロセス間で共有されていることを示しています。
PHPが同じSAPIを使用していることを確認してください(たとえば、CLIモードで複数の子プロセスを実行します) 。
APC.ENABLE_CLI = 1がPHP.iniで有効になっていることを確認します。そうしないと、APCUはCLIモードでは有効になりません。
APCUは、マルチサーバーキャッシュの共有には適していません(ロードバランシング中の複数のPHPインスタンスなど) 。マルチマシンキャッシュが必要な場合は、Redis、Memcached、その他のサービスを使用してください。
キャッシュの持続性への過度の依存を避け、APCUはプロセスレベルのキャッシュであり、PHP-FPMを再起動するとデータの損失が発生します。
リモートAPIから構成データを取得するとします。
$config = apcu_entry('remote_config', function () {
echo "リモートインターフェイスからデータを取得します...\n";
$json = file_get_contents('https://gitbox.net/api/config');
return json_decode($json, true);
});
キャッシュが期限切れになっていない限り、このロジックを呼び出すプロセスはありません。インターフェイスを繰り返し要求します。これにより、パフォーマンスが大幅に向上し、リモートコールの数が減少します。
APCU_Entryは、特に「高い計算コストまたは高コールコスト」のシナリオに適したエレガントなキャッシュメカニズムを提供します。マルチプロセスPHPプログラムでは、APCUのキャッシュコンテンツは、実行中の環境が許可されている限り、プロセス間で共有できます。その運用原則と制限を理解することで、高性能PHPアプリケーションをより効率的に構築することができます。