У меня есть простой скрипт PHP, который вычисляет некоторые вещи о заданном вводе строки. Он кэширует результаты в базе данных, и мы время от времени удаляем записи, которые старше определенного количества дней.
Наши программисты реализовали эту базу данных как:
function cachedCalculateThing($input) {
$cacheFile = 'cache/' . sha1($input) . '.dat';
if (file_exists($cacheFile) {
return json_decode(file_get_contents($cacheFile));
}
$retval = ...
file_put_contents(json_encode($retval));
}
function cleanCache() {
$stale = time() - 7*24*3600;
foreach (new DirectoryIterator('cache/') as $fileInfo) {
if ($fileInfo->isFile() && $fileInfo->getCTime() < $stale) {
unlink($fileInfo->getRealPath());
}
}
Мы используем Ubuntu LAMP и ext3. При каком количестве записей поиск в кэше становится непостоянным или нарушает жесткий лимит?
Хотя этот конкретный код не очень «масштабируемый» *, существует ряд вещей, которые могут его улучшить:
iostat -x 4
и посмотрите текущее использование диска. Если оно уже выше, чем, скажем, 25%, включение кэширования диска увеличит его до 100% в случайное время и замедлит работу всех веб-служб. (Поскольку запросы к диску должны быть поставлены в очередь и обслуживаться (обычно) по порядку (не всегда, но не рассчитывайте на это)).* Для масштабируемости это обычно определяется в терминах скорости линейного запроса или ресурсов параллельного сервера. Этот код:
find ./cache -type f -mtime +7 -exec rm -f "{}" \;
Основной вывод заключается в том, что для достижения реальной масштабируемости и хорошей производительности системы кэширования необходимо уделить немного больше внимания, чем показано в коротком блоке кода. Может быть больше ограничений, чем те, которые я перечислил, но даже они зависят от таких переменных, как размер, количество записей, количество запросов / сек, текущая загрузка диска, тип файловой системы и т. Д. — внешние вещи к коду. Что и следовало ожидать, потому что кеш сохраняется вне кода. Приведенный код может работать для небольшого набора кэширования с небольшим количеством запросов, но не для больших размеров, для которых требуется кэширование.
Кроме того, вы используете Apache в режиме потока или prefork? Это повлияет на то, как php блокирует чтение и запись.
— Хм, наверное, мне следовало добавить, что вы хотите отслеживать свой объект и ключ / хэш. Если $ input уже является строкой, она находится в своей базовой форме / уже вычислена, извлечена, сериализована и т. Д. Если $ input является ключом, то file_put_contents () должен поместить что-то еще (фактическую переменную / содержимое). Если $ input — это объект для поиска (который может быть похож на длинную строку или даже короткую), тогда ему нужен ключ поиска, в противном случае никакие вычисления не будут пропущены / сохранены.
Других решений пока нет …