在大型 php 应用程序中写入文件的最佳方法是什么。可以说每秒需要大量写入。最好的方法是如何解决这个问题。
我可以打开文件并附加数据吗?或者我应该打开、锁定、写入和解锁。
文件会发生什么,需要写入其他数据。这个活动会丢失,还是会被保存。如果这将被保存将停止应用程序。
如果你去过,谢谢你的阅读!
这是一个简单的例子,突出了同时写的危险:
<?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
这是因为文件追加仅在以下情况下是原子的:
如果您在日志追加期间对 fwrite 进行了多次调用,或者您写入的内容超过了 4k,那么所有的赌注都将被取消。
现在,至于这是否重要:您是否可以在重负载的情况下在日志中有一些损坏的行?老实说,大多数时候这是完全可以接受的,您可以避免文件锁定的开销。
我确实有高性能的多线程应用程序,其中所有线程都在写入(附加)到单个日志文件。到目前为止,没有注意到任何问题,每个线程每秒写入多次,并且没有任何丢失。我认为只是附加到大文件应该没有问题。但是如果你想修改已经存在的内容,尤其是并发性——我会选择锁定,否则可能会发生大混乱......
如果并发是一个问题,那么您真的应该使用数据库。
如果你只是写日志,也许你需要看看 syslog 函数,因为syslog提供了一个 api。您还应该将写入委托给专门的后端并以异步方式完成工作吗?
这些是我的 2p。
除非出于特定原因需要一个唯一的文件,否则我会避免将所有内容附加到一个巨大的文件中。相反,我会按时间和维度包装文件。可以为此定义几个配置参数(wrap_time 和 wrap_size)。
另外,我可能会引入一些缓冲以避免等待写操作完成。
可能 PHP 不是最适合这种操作的语言,但它仍然是可能的。
如果您只需要追加数据,PHP 应该可以,因为文件系统应该负责同时追加。