はじめに
PHPアプリケーションのパフォーマンスを向上させるには、ファイルシステムアクセスの最適化が欠かせません。PHPは内部的にファイルパスの解決結果をキャッシュしており、このキャッシュのサイズを把握することが重要です。
realpath_cache_size関数を使うと、現在使用されているrealpathキャッシュのサイズを確認でき、適切な設定値を決定できます。この記事では、realpath_cache_size関数の使い方から、実践的なキャッシュサイズの最適化方法まで、詳しく解説していきます。
realpath_cache_size関数とは?
realpath_cache_size関数は、現在使用されているrealpathキャッシュのサイズをバイト単位で取得する関数です。キャッシュがどれだけのメモリを消費しているかを確認できます。
基本的な構文
<?php
realpath_cache_size(): int
?>
- 引数: なし
- 戻り値: 使用中のキャッシュサイズ(バイト単位)
最もシンプルな使用例
<?php
$size = realpath_cache_size();
echo "使用中のキャッシュサイズ: {$size} バイト\n";
// 読みやすく変換
$sizeMB = round($size / 1024 / 1024, 2);
echo "使用中のキャッシュサイズ: {$sizeMB} MB\n";
?>
realpathキャッシュサイズの重要性
なぜキャッシュサイズが重要なのか?
- パフォーマンスへの影響: キャッシュサイズが小さすぎると、頻繁にキャッシュが破棄され、ファイルシステムへのアクセスが増加します
- メモリ使用量: 大きすぎる設定は無駄なメモリ消費につながります
- 最適化の指標: 現在の使用量を知ることで、適切な設定値を決定できます
キャッシュサイズの確認方法
<?php
function getCacheSizeInfo() {
$usedSize = realpath_cache_size();
$maxSize = ini_get('realpath_cache_size');
// 最大サイズをバイトに変換
$maxSizeBytes = parseSize($maxSize);
// 使用率を計算
$usage = ($usedSize / $maxSizeBytes) * 100;
return [
'used_bytes' => $usedSize,
'used_formatted' => formatBytes($usedSize),
'max_size' => $maxSize,
'max_bytes' => $maxSizeBytes,
'max_formatted' => formatBytes($maxSizeBytes),
'usage_percent' => round($usage, 2),
'available_bytes' => $maxSizeBytes - $usedSize,
'available_formatted' => formatBytes($maxSizeBytes - $usedSize)
];
}
function parseSize($size) {
$unit = strtolower(substr($size, -1));
$value = (int)$size;
switch ($unit) {
case 'g': return $value * 1024 * 1024 * 1024;
case 'm': return $value * 1024 * 1024;
case 'k': return $value * 1024;
default: return $value;
}
}
function formatBytes($bytes) {
$units = ['B', 'KB', 'MB', 'GB'];
$i = 0;
while ($bytes >= 1024 && $i < count($units) - 1) {
$bytes /= 1024;
$i++;
}
return round($bytes, 2) . ' ' . $units[$i];
}
// 使用例
$info = getCacheSizeInfo();
echo "=== realpathキャッシュ情報 ===\n";
echo "使用中: {$info['used_formatted']}\n";
echo "最大サイズ: {$info['max_formatted']}\n";
echo "使用率: {$info['usage_percent']}%\n";
echo "空き容量: {$info['available_formatted']}\n";
?>
実践的な使用例
1. キャッシュサイズのモニタリング
<?php
class CacheSizeMonitor {
private $threshold;
public function __construct($warningThreshold = 80, $criticalThreshold = 90) {
$this->warningThreshold = $warningThreshold;
$this->criticalThreshold = $criticalThreshold;
}
public function check() {
$usedSize = realpath_cache_size();
$maxSize = parseSize(ini_get('realpath_cache_size'));
$usage = ($usedSize / $maxSize) * 100;
$status = 'ok';
$message = 'キャッシュサイズは正常です';
if ($usage >= $this->criticalThreshold) {
$status = 'critical';
$message = sprintf(
'キャッシュ使用率が危険レベル: %.2f%% (%s / %s)',
$usage,
formatBytes($usedSize),
formatBytes($maxSize)
);
} elseif ($usage >= $this->warningThreshold) {
$status = 'warning';
$message = sprintf(
'キャッシュ使用率が高い: %.2f%% (%s / %s)',
$usage,
formatBytes($usedSize),
formatBytes($maxSize)
);
}
return [
'status' => $status,
'usage_percent' => round($usage, 2),
'used_size' => $usedSize,
'max_size' => $maxSize,
'message' => $message
];
}
public function log() {
$result = $this->check();
$logEntry = sprintf(
"[%s] %s - Status: %s, Usage: %.2f%%\n",
date('Y-m-d H:i:s'),
$result['message'],
$result['status'],
$result['usage_percent']
);
error_log($logEntry);
return $result;
}
}
// 使用例
$monitor = new CacheSizeMonitor();
$result = $monitor->check();
echo $result['message'] . "\n";
if ($result['status'] !== 'ok') {
echo "⚠ アクション推奨: realpath_cache_sizeの増加を検討してください\n";
}
?>
2. アプリケーション起動時のキャッシュサイズチェック
<?php
/**
* アプリケーション起動時にキャッシュサイズをチェック
*/
function checkCacheOnStartup() {
$usedSize = realpath_cache_size();
$maxSize = parseSize(ini_get('realpath_cache_size'));
$usage = ($usedSize / $maxSize) * 100;
// ログに記録
$logData = [
'timestamp' => date('Y-m-d H:i:s'),
'used_size' => formatBytes($usedSize),
'max_size' => formatBytes($maxSize),
'usage_percent' => round($usage, 2),
'entries' => count(realpath_cache_get())
];
error_log('Realpath Cache Startup: ' . json_encode($logData));
// 警告閾値を超えている場合
if ($usage > 80) {
trigger_error(
sprintf(
'Realpath cache usage is high: %.2f%% (%s / %s)',
$usage,
formatBytes($usedSize),
formatBytes($maxSize)
),
E_USER_WARNING
);
}
return $logData;
}
// アプリケーション起動時に実行
checkCacheOnStartup();
?>
3. キャッシュサイズの推移を追跡
<?php
class CacheSizeTracker {
private $dataFile;
public function __construct($dataFile = '/tmp/cache_size_history.json') {
$this->dataFile = $dataFile;
}
public function record() {
$currentSize = realpath_cache_size();
$maxSize = parseSize(ini_get('realpath_cache_size'));
$data = $this->loadHistory();
$data[] = [
'timestamp' => time(),
'datetime' => date('Y-m-d H:i:s'),
'size' => $currentSize,
'max_size' => $maxSize,
'usage_percent' => round(($currentSize / $maxSize) * 100, 2),
'entries' => count(realpath_cache_get())
];
// 最新1000件のみ保持
if (count($data) > 1000) {
$data = array_slice($data, -1000);
}
$this->saveHistory($data);
}
public function getStats($hours = 24) {
$data = $this->loadHistory();
$cutoff = time() - ($hours * 3600);
// 指定時間内のデータのみフィルタ
$recentData = array_filter($data, function($entry) use ($cutoff) {
return $entry['timestamp'] >= $cutoff;
});
if (empty($recentData)) {
return null;
}
$sizes = array_column($recentData, 'size');
$usages = array_column($recentData, 'usage_percent');
return [
'period_hours' => $hours,
'samples' => count($recentData),
'size_min' => formatBytes(min($sizes)),
'size_max' => formatBytes(max($sizes)),
'size_avg' => formatBytes(array_sum($sizes) / count($sizes)),
'usage_min' => round(min($usages), 2),
'usage_max' => round(max($usages), 2),
'usage_avg' => round(array_sum($usages) / count($usages), 2),
'current_size' => formatBytes(end($recentData)['size']),
'current_usage' => end($recentData)['usage_percent']
];
}
private function loadHistory() {
if (!file_exists($this->dataFile)) {
return [];
}
$json = file_get_contents($this->dataFile);
return json_decode($json, true) ?: [];
}
private function saveHistory($data) {
file_put_contents($this->dataFile, json_encode($data));
}
}
// 使用例
$tracker = new CacheSizeTracker();
// 定期的に実行(cronなど)
$tracker->record();
// 統計情報の取得
$stats = $tracker->getStats(24);
if ($stats) {
echo "=== 過去24時間の統計 ===\n";
echo "サンプル数: {$stats['samples']}\n";
echo "最小サイズ: {$stats['size_min']}\n";
echo "最大サイズ: {$stats['size_max']}\n";
echo "平均サイズ: {$stats['size_avg']}\n";
echo "平均使用率: {$stats['usage_avg']}%\n";
}
?>
4. リアルタイムダッシュボード
<?php
/**
* キャッシュサイズのリアルタイムダッシュボード
*/
function displayCacheDashboard() {
$usedSize = realpath_cache_size();
$cache = realpath_cache_get();
$maxSize = parseSize(ini_get('realpath_cache_size'));
$ttl = ini_get('realpath_cache_ttl');
$usage = ($usedSize / $maxSize) * 100;
$entryCount = count($cache);
$avgEntrySize = $entryCount > 0 ? $usedSize / $entryCount : 0;
// 統計情報
$fileCount = 0;
$dirCount = 0;
foreach ($cache as $entry) {
if ($entry['is_dir']) {
$dirCount++;
} else {
$fileCount++;
}
}
echo "╔════════════════════════════════════════════════╗\n";
echo "║ Realpath Cache ダッシュボード ║\n";
echo "╠════════════════════════════════════════════════╣\n";
printf("║ 使用サイズ: %-35s║\n", formatBytes($usedSize));
printf("║ 最大サイズ: %-35s║\n", formatBytes($maxSize));
printf("║ 使用率: %-39s║\n", sprintf("%.2f%%", $usage));
echo "╠════════════════════════════════════════════════╣\n";
printf("║ 総エントリ数: %-32d║\n", $entryCount);
printf("║ ファイル: %-36d║\n", $fileCount);
printf("║ ディレクトリ: %-32d║\n", $dirCount);
printf("║ エントリ平均サイズ: %-27s║\n", formatBytes($avgEntrySize));
echo "╠════════════════════════════════════════════════╣\n";
printf("║ TTL: %-42d║\n", $ttl);
printf("║ 空き容量: %-36s║\n", formatBytes($maxSize - $usedSize));
echo "╠════════════════════════════════════════════════╣\n";
// ステータス表示
if ($usage >= 90) {
echo "║ ステータス: 🔴 危険 - 即座の対応が必要 ║\n";
} elseif ($usage >= 80) {
echo "║ ステータス: 🟡 警告 - サイズ増加を検討 ║\n";
} elseif ($usage >= 70) {
echo "║ ステータス: 🟢 注意 - モニタリング継続 ║\n";
} else {
echo "║ ステータス: ✅ 正常 ║\n";
}
echo "╚════════════════════════════════════════════════╝\n";
}
// 使用例
displayCacheDashboard();
?>
5. 自動アラートシステム
<?php
class CacheSizeAlertSystem {
private $config;
public function __construct($config = []) {
$this->config = array_merge([
'warning_threshold' => 80,
'critical_threshold' => 90,
'alert_cooldown' => 3600, // 1時間
'state_file' => '/tmp/cache_alert_state.json'
], $config);
}
public function checkAndAlert() {
$usedSize = realpath_cache_size();
$maxSize = parseSize(ini_get('realpath_cache_size'));
$usage = ($usedSize / $maxSize) * 100;
$state = $this->loadState();
$now = time();
// アラートレベルの判定
$level = null;
if ($usage >= $this->config['critical_threshold']) {
$level = 'critical';
} elseif ($usage >= $this->config['warning_threshold']) {
$level = 'warning';
}
// アラートが必要かチェック
if ($level && $this->shouldAlert($level, $state, $now)) {
$this->sendAlert($level, $usage, $usedSize, $maxSize);
$this->updateState($level, $now);
}
return [
'level' => $level,
'usage' => round($usage, 2),
'alerted' => $level !== null
];
}
private function shouldAlert($level, $state, $now) {
if (!isset($state['last_alert'][$level])) {
return true;
}
$lastAlert = $state['last_alert'][$level];
return ($now - $lastAlert) >= $this->config['alert_cooldown'];
}
private function sendAlert($level, $usage, $usedSize, $maxSize) {
$message = sprintf(
"[%s] Realpath Cache Alert: %s\n" .
"使用率: %.2f%%\n" .
"使用サイズ: %s / %s\n" .
"推奨アクション: realpath_cache_sizeを増やしてください\n",
strtoupper($level),
$level === 'critical' ? '緊急' : '警告',
$usage,
formatBytes($usedSize),
formatBytes($maxSize)
);
// ログに記録
error_log($message);
// メール送信やSlack通知など(実装例)
// $this->sendEmail($message);
// $this->sendSlackNotification($message);
echo $message;
}
private function loadState() {
if (!file_exists($this->config['state_file'])) {
return ['last_alert' => []];
}
$json = file_get_contents($this->config['state_file']);
return json_decode($json, true) ?: ['last_alert' => []];
}
private function updateState($level, $timestamp) {
$state = $this->loadState();
$state['last_alert'][$level] = $timestamp;
file_put_contents($this->config['state_file'], json_encode($state));
}
}
// 使用例(cronで定期実行)
$alertSystem = new CacheSizeAlertSystem([
'warning_threshold' => 75,
'critical_threshold' => 85
]);
$result = $alertSystem->checkAndAlert();
echo "チェック完了 - レベル: " . ($result['level'] ?? 'なし') . "\n";
?>
6. パフォーマンステスト
<?php
/**
* キャッシュサイズがパフォーマンスに与える影響をテスト
*/
class CacheSizePerformanceTest {
public function run($iterations = 1000) {
echo "=== キャッシュパフォーマンステスト ===\n\n";
// テスト前の状態
$beforeSize = realpath_cache_size();
$beforeEntries = count(realpath_cache_get());
echo "開始時のキャッシュサイズ: " . formatBytes($beforeSize) . "\n";
echo "開始時のエントリ数: {$beforeEntries}\n\n";
// テスト実行
$startTime = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
// ファイル操作をシミュレート
$path = __DIR__ . '/test_' . ($i % 100) . '.php';
@realpath($path);
@file_exists($path);
}
$endTime = microtime(true);
$duration = $endTime - $startTime;
// テスト後の状態
$afterSize = realpath_cache_size();
$afterEntries = count(realpath_cache_get());
echo "テスト完了\n";
echo "実行時間: " . round($duration * 1000, 2) . " ms\n";
echo "操作数: {$iterations}\n";
echo "平均処理時間: " . round(($duration / $iterations) * 1000000, 2) . " μs\n\n";
echo "終了時のキャッシュサイズ: " . formatBytes($afterSize) . "\n";
echo "終了時のエントリ数: {$afterEntries}\n\n";
$sizeIncrease = $afterSize - $beforeSize;
$entryIncrease = $afterEntries - $beforeEntries;
echo "サイズ増加: " . formatBytes($sizeIncrease) . "\n";
echo "エントリ増加: {$entryIncrease}\n";
if ($entryIncrease > 0) {
$avgEntrySize = $sizeIncrease / $entryIncrease;
echo "エントリ平均サイズ: " . formatBytes($avgEntrySize) . "\n";
}
}
}
// 使用例
$test = new CacheSizePerformanceTest();
$test->run(1000);
?>
最適なキャッシュサイズの決定
サイズ決定のガイドライン
<?php
function recommendCacheSize() {
// 現在の使用状況を確認
$currentSize = realpath_cache_size();
$currentEntries = count(realpath_cache_get());
$currentMax = parseSize(ini_get('realpath_cache_size'));
// 使用率を計算
$usage = ($currentSize / $currentMax) * 100;
echo "=== キャッシュサイズ推奨設定 ===\n\n";
echo "現在の設定\n";
echo " 最大サイズ: " . formatBytes($currentMax) . "\n";
echo " 使用サイズ: " . formatBytes($currentSize) . "\n";
echo " 使用率: " . round($usage, 2) . "%\n";
echo " エントリ数: {$currentEntries}\n\n";
// 推奨サイズの計算
$recommendedSize = $currentSize * 1.5; // 現在の1.5倍
// 最小値と最大値の制限
$minSize = 4 * 1024 * 1024; // 最小4MB
$maxSize = 256 * 1024 * 1024; // 最大256MB
if ($recommendedSize < $minSize) {
$recommendedSize = $minSize;
} elseif ($recommendedSize > $maxSize) {
$recommendedSize = $maxSize;
}
$recommendedSizeMB = ceil($recommendedSize / 1024 / 1024);
echo "推奨設定\n";
echo " realpath_cache_size = {$recommendedSizeMB}M\n\n";
// 設定方法の説明
echo "設定方法:\n";
echo "1. php.iniに追加:\n";
echo " realpath_cache_size = {$recommendedSizeMB}M\n\n";
echo "2. php-fpmの場合 (pool設定):\n";
echo " php_admin_value[realpath_cache_size] = {$recommendedSizeMB}M\n\n";
// アプリケーションタイプ別の推奨値
echo "アプリケーションタイプ別の推奨値:\n";
echo " 小規模アプリ: 4M - 8M\n";
echo " 中規模アプリ: 16M - 32M\n";
echo " 大規模アプリ: 64M - 128M\n";
echo " 超大規模アプリ: 128M - 256M\n";
}
recommendCacheSize();
?>
まとめ
realpath_cache_size関数のポイントをおさらいしましょう:
- 現在使用中のキャッシュサイズをバイト単位で取得
- キャッシュ使用率の監視に不可欠
- パフォーマンス最適化の重要な指標
- 使用率が80%を超えたら設定の見直しが必要
- 定期的なモニタリングでパフォーマンスを維持
- アプリケーション規模に応じた適切なサイズ設定が重要
- realpath_cache_get()と組み合わせて詳細分析
realpathキャッシュのサイズを適切に管理することで、PHPアプリケーションのパフォーマンスを大幅に向上させることができます。realpath_cache_size関数を活用して、最適な設定を見つけましょう!
参考リンク
この記事が役に立ったら、ぜひシェアしてください!PHPに関する他の記事もお楽しみに。
