abrir arquivo bloqueado em PHP (tipo de situação de leitor / gravador)

Eu tenho um cenário em que um processo PHP está gravando um arquivo cerca de 3 vezes por segundo e, em seguida, vários processos PHP estão lendo esse arquivo.

Este arquivo é essencialmente um cache. Nosso site tem uma pesquisa muito insistente, para dados que mudam constantemente e não queremos que todos os visitantes acessem o banco de dados toda vez que pesquisam, por isso, temos um processo cron que lê o banco de dados 3 vezes por segundo, processa os dados, e o despeja em um arquivo que os clientes de pesquisa podem ler.

O problema que estou tendo é que, às vezes, abrir o arquivo para gravar leva muito tempo, às vezes até 2-3 segundos. Eu estouassumindo isso acontece porque está sendo bloqueado por leituras (ou por alguma coisa), mas não tenho nenhuma maneira conclusiva de provar que, além disso, de acordo com o que entendo na documentação, o PHP não deveria estar bloqueando nada. Isso acontece a cada 2-5 minutos, por isso é bastante comum.

No código, eu não estou fazendoqualquer tipo de bloqueio, e eu praticamente não me importo se as informações desse arquivo forem corrompidas, se uma leitura falhar ou se os dados forem alterados no meio de uma leitura. Eu me importo, no entanto, se escrever para ele leva 2 segundos, basicamente, porque o processo que tem que acontecer três vezes por segundo agora pulou várias batidas.

Estou escrevendo o arquivo com este código:

$handle = fopen(DIR_PUBLIC . 'filename.txt', "w");
fwrite($handle, $data);
fclose($handle);

E eu estou lendo diretamente com:

file_get_contents('filename.txt')

(não está sendo veiculado diretamente para os clientes como um arquivo estático, estou recebendo uma solicitação PHP regular que lê o arquivo e faz algumas coisas básicas com ele)

O arquivo tem cerca de 11kb, portanto, não leva muito tempo para ler / gravar. Bem abaixo de 1ms.

Esta é uma entrada de log típica quando o problema ocorre:

  Open File:    2657.27 ms
  Write:    0.05984 ms
  Close:    0.03886 ms

Não tenho certeza se é relevante, mas as leituras ocorrem em solicitações regulares da Web, através do apache, mas a gravação é uma execução PHP "de linha de comando" regular feita pelo cron do Linux, não está passando pelo Apache.

Alguma idéia do que poderia estar causando esse grande atraso na abertura do arquivo?
Alguma indicação de onde eu poderia procurar para me ajudar a identificar a causa real?

Como alternativa, você pode pensar em algo que eu poderia fazer para evitar isso? Por exemplo, eu adoraria poder definir um tempo limite de 50ms para abrir e, se ele não abrir o arquivo, ele apenas pula para a frente e permite que a próxima execução do cron cuide dele.

Novamente, minha prioridade é manter o cron batendo três vezes por segundo; todo o resto é secundário; portanto, quaisquer idéias, sugestões e qualquer coisa são extremamente bem-vindas.

Obrigado!
Daniel

questionAnswers(2)

yourAnswerToTheQuestion