如何在大型php应用程序中写入文件(多个问题)

Sai*_*han 7 php file append flock

在大型php应用程序中写入文件的最佳方法是什么.可以说每秒需要大量的写入.怎样才能解决这个问题.

我可以打开文件并附加数据.或者我应该打开,锁定,写入和解锁.

将处理该文件将会发生什么,并且需要编写其他数据.这项活动会丢失,还是会被保存.如果这将被保存将停止应用程序.

如果你去过,谢谢你的阅读!

Fra*_*mer 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";
Run Code Online (Sandbox Code Playgroud)

如果附加是安全的,你应该得到一个包含100行的文件,所有这些行大约有10,000个字符长,并以整数开头.有时候,当你运行这个脚本时,这正是你得到的.有时,一些附加物会发生冲突,但它会受到损害.

你可以找到损坏的线条 grep '^[^0-9]' test.txt

这是因为在以下情况下,文件附加只是原子的:

  1. 你进行一次fwrite()调用
  2. 并且fwrite()小于PIPE_BUF(大约1-4k)
  3. 并且您写入完全符合POSIX的文件系统

如果您在日志追加期间对fwrite进行多次调用,或者您写的数量超过4k,则所有投注均已关闭.

现在,关于这是否重要:你是否可以在重载下的日志中有一些损坏的行?老实说,大多数时候这是完全可以接受的,你可以避免文件锁定的开销.


Lai*_*jus 6

我确实有高性能的多线程应用程序,其中所有线程都在写入(追加)到单个日志文件.到目前为止,没有发现任何问题,每个线程每秒写入多次,没有任何东西丢失.我认为只是追加巨大的文件应该没有问题.但是如果你想修改已经存在的内容,特别是并发 - 我会选择锁定,否则会发生大混乱...