在大型php应用程序中写入文件的最佳方法是什么。可以说每秒需要大量的写入。怎样才能解决这个问题。
我可以打开文件并附加数据。或者我应该打开,锁定,写入和解锁。
该文件将会发生什么,需要编写其他数据。这项活动会丢失,还是会被保存。如果保存这将停止申请。
如果你去过,谢谢你的阅读!
答案 0 :(得分:9)
这是一个简单的例子,突出了同时存在的危险:
<?php
for($i = 0; $i < 100; $i++) {
$pid = pcntl_fork();
//only spawn more children if we're not a child ourselves
if(!$pid)
break;
}
$fh = fopen('test.txt', 'a');
//The following is a simple attempt to get multiple threads to start at the same time.
$until = round(ceil(time() / 10.0) * 10);
echo "Sleeping until $until\n";
time_sleep_until($until);
$myPid = posix_getpid();
//create a line starting with pid, followed by 10,000 copies of
//a "random" char based on pid.
$line = $myPid . str_repeat(chr(ord('A')+$myPid%25), 10000) . "\n";
for($i = 0; $i < 1; $i++) {
fwrite($fh, $line);
}
fclose($fh);
echo "done\n";
如果附加是安全的,你应该得到一个包含100行的文件,所有文件大约有10,000个字符长,并以整数开头。有时候,当你运行这个脚本时,这正是你得到的。有时,一些附加物会发生冲突,但它会受到损害。
您可以使用grep '^[^0-9]' test.txt
这是因为file append is only atomic if:
如果您在日志追加期间多次拨打fwrite,或者您的写入次数超过4k,则所有投注均已关闭。
现在,关于这是否重要:您是否可以在负载较重的情况下在日志中出现一些损坏的线路?老实说,大多数时候这是完全可以接受的,你可以避免文件锁定的开销。
答案 1 :(得分:6)
我确实有高性能的多线程应用程序,其中所有线程都在写入(追加)到单个日志文件。到目前为止,没有发现任何问题,每个线程每秒写入多次,没有任何东西丢失。我认为只是追加巨大的文件应该没有问题。但是如果你想修改已经存在的内容,尤其是并发 - 我会选择锁定,否则会发生大混乱...
答案 2 :(得分:4)
如果并发是个问题,那么你应该真正使用数据库。
答案 3 :(得分:1)
如果您只是编写日志,可能需要查看syslog函数,因为syslog提供了api。 您还应该将写入委托给专用的后端并在异步的maneer中完成工作吗?
答案 4 :(得分:1)
这些是我的2p。
除非出于特定原因需要一个唯一的文件,否则我会避免将所有内容附加到一个巨大的文件中。相反,我会按时间和维度包装文件。可以为此定义几个配置参数(wrap_time和wrap_size)。
另外,我可能会介绍一些缓冲以避免等待写操作完成。
对于这种操作来说,PHP可能不是最适合的语言,但它仍然是可能的。
答案 5 :(得分:0)
答案 6 :(得分:-3)
如果您只需要附加数据,那么PHP应该没问题,因为文件系统应该同时处理附加内容。