服务器文件读/写并发问题

时间:2011-03-29 13:29:40

标签: php apache

我有一个从MySQL数据库服务的网络服务。我想创建缓存文件以提高性能。这个想法曾经有一段时间我们从数据库中读取数据并生成一个文本文件。我的问题是:

如果客户端用户在生成文件时访问该文件会怎样?

我们正在使用LAMP。在PHP中有flock()处理并发问题,但我的理解是它只适用于2个PHP进程同时访问文件的情况。我们的情况不同。

我不知道这是否会引起问题。如果是这样,我该如何预防呢?

谢谢,

5 个答案:

答案 0 :(得分:2)

不要使用锁定; 如果您的缓存文件是/tmp/cache.txt,那么您应该始终将缓存重新生成为/tmp/cache2.txt然后执行

mv /tmp/cache2.txt /tmp/cache.txt 

rename('/tmp/cache2.txt','/tmp/cache.txt')

如果mv / rename操作发生在同一个文件系统中,则它是原子操作;不需要锁定

答案 1 :(得分:1)

此处有各种优化选项;

1)您使用的是MySQL queryCache - 从数据库开始可以承担巨大的负担。

2)你可以通过像squid这样的web代理(或者配置为反向缓存代理的Apache)来提取文件。我一直这样做,这是一个非常方便的技术 - 通过使用wget从URL获取文件来生成文件(这样你可以在cron作业中使用它)。 Web代理负责提供之前的相同文件,或者在需要时重新生成它。

3)您不希望在这种情况下滚动自己的文件锁定解决方案。

根据您的情况,您还可以考虑将页面缓存在类似于memcache的内容中,这对于高流量场景非常有用,但可能超出了此问题的范围。

答案 2 :(得分:1)

您可以使用A - > B切换以避免此问题。

E.g。 :让这个缓存文件A和B有两个副本,程序应该通过符号链接C来读取它们。

当程序正在构建缓存时,它会修改不是“当前”的文件。如果C链接到A,则更新B.更新完成后,将符号链接切换到B.

下次更新A并在完成更新后将符号链接切换为A.

这样客户端在更新文件时永远不会读取文件。

答案 3 :(得分:0)

当客户端访问文件时,它会在那一刻读取它。 flock()用于2个PHP进程同时访问文件。

答案 4 :(得分:0)

我会这样解决:

  • 在生成新文本文件时,将其保存到临时文件(cache.tmp),这样就像以前一样访问旧文件(cache.txt)。
  • 生成完成后,删除旧文件并重命名新文件
  • 为了避免在这么短的时间内出现问题,您的代码应检查是否存在cache.txt,并在短时间内重试。

琐碎,但应该做的伎俩