У меня есть сценарий, когда один процесс PHP пишет файл примерно 3 раза в секунду, а затем несколько PHP-процессов читают этот файл.
Этот файл представляет собой кеш. На нашем сайте очень настойчивый опрос, который постоянно меняется, и мы не хотим, чтобы каждый посетитель попадал в БД каждый раз, когда они опросили, поэтому у нас есть процесс cron, который читает DB 3 раза в секунду, обрабатывает данные, и выгружает его в файл, который затем могут считывать клиенты опроса.
Проблема, с которой я сталкиваюсь, заключается в том, что иногда открытие файла для записи занимает много времени, иногда даже до 2-3 секунд. Я предполагаю, что это происходит из-за того, что он заблокирован чтением (или чем-то), но у меня нет убедительного доказательства этого, плюс, согласно тому, что я понимаю из документации, PHP не должен блокировать что-либо , Это происходит каждые 2-5 минут, так что это довольно часто.
В коде я не занимаюсь какой- либо блокировкой, и мне почти все равно, повреждена ли информация этого файла, если сбой чтения, или если данные изменяются в середине чтения. Тем не менее, мне все равно, если письмо на это занимает 2 секунды, в частности, потому что процесс, который должен произойти трижды в секунду, пропустил несколько ударов.
Я пишу файл с этим кодом:
$handle = fopen(DIR_PUBLIC . 'filename.txt', "w"); fwrite($handle, $data); fclose($handle);
И я читаю его напрямую:
file_get_contents('filename.txt')
(он не доставляется непосредственно клиентам как статический файл, я получаю регулярный PHP-запрос, который читает файл и делает некоторые базовые вещи с ним)
Файл составляет около 11kb, поэтому для чтения / записи не требуется много времени. Хорошо под 1 мс.
Это типичная запись в журнале, когда возникает проблема:
Open File: 2657.27 ms Write: 0.05984 ms Close: 0.03886 ms
Не уверен, что это актуально, но чтение происходит в обычных веб-запросах через apache, но запись – это обычная «командная строка» PHP-исполнения, выполняемая cron Linux, она не проходит через Apache.
Любые идеи о том, что может вызвать эту большую задержку при открытии файла?
Любые указатели на то, где я мог бы посмотреть, чтобы помочь мне определить фактическую причину?
Или вы можете думать о чем-то, что я мог бы сделать, чтобы избежать этого? Например, мне бы хотелось установить 50-минутный тайм-аут для открытия, и если он не откроет файл, он просто пропустит вперед и позволит выполнить следующий запуск cron.
Опять же, мой приоритет заключается в том, чтобы держать cron бить три раза, все остальное вторично, поэтому любые идеи, предложения, что-то очень приветствуются.
Спасибо!
Даниил
Я могу думать о 3 возможных проблемах:
Решения, о которых я могу думать:
Вы должны использовать что-то действительно быстрое решение, если хотите гарантировать постоянное низкое время открывания. Возможно, ваша ОС выполняет синхронизацию диска, файл базы данных или другие вещи, с которыми вы не можете работать.
Я предлагаю использовать memcached, redis или даже mongoDB для таких задач. Вы даже можете написать свой собственный демон кэширования, даже в php (однако это совершенно не нужно и может быть сложным).
Если вы абсолютно уверены, что вы можете решить эту задачу только этим кешем файлов, и вы находитесь под Linux, попробуйте использовать другой планировщик ввода-вывода на диске, например, крайний срок, OR (cfq И уменьшите приоритет PHP-процесса до -3 / -4).