我有一个场景,其中一个PHP进程每秒写入一次文件大约3次,然后有几个PHP进程正在读取此文件。
这个文件实际上是一个缓存。我们的网站有一个非常坚持的轮询,对于不断变化的数据,我们不希望每个访问者在每次轮询时都访问数据库,因此我们有一个cron进程,每秒读取数据库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,因此不需要花费大量时间来读/写。差不多1ms。
这是问题发生时的典型日志条目:
Open File: 2657.27 ms
Write: 0.05984 ms
Close: 0.03886 ms
不确定它是否相关,但是读取是通过apache在常规Web请求中发生的,但是写入是由Linux的cron执行的常规“命令行”PHP执行,而不是通过Apache。
有什么想法可能会导致打开文件出现这么大的延迟? 我可以看到哪些指针帮助我查明实际原因?
或者,你能想到我能做些什么来避免这种情况吗?例如,我希望能够设置一个50ms的超时来fopen,如果它没有打开文件,它只是向前跳过,并让cron的下一次运行来处理它。
同样,我的首要任务是让cron一秒钟跳三次,其他都是次要的,所以任何想法,建议,任何事情都是非常受欢迎的。
谢谢! 丹尼尔
答案 0 :(得分:3)
我可以想到3个可能的问题:
我能想到的解决方案:
答案 1 :(得分:0)
如果您想保证持续的低开放时间,您应该使用真正的快速解决方案。也许您的操作系统正在进行磁盘同步,数据库文件提交或其他无法解决的问题。
我建议使用memcached,redis甚至mongoDB来完成这些任务。您甚至可以编写自己的缓存守护进程,即使在php中也是如此(但这完全没必要,而且可能很棘手)。
如果您是绝对的,请确定您只能通过此文件缓存解决此任务,并且您在Linux下,尝试使用不同的磁盘I / O调度程序,如截止日期,或者(cfq并将PHP进程优先级降低到-3 / -4)。