Как записать в файл в большом php приложении (несколько вопросов)

Что является лучшим способом записать в файлы в большом php приложении. Позволяет говорят, что существует много записей, необходимых в секунду. Как лучший способ состоит в том, чтобы пойти об этом.

Я мог просто открыть файл и добавить данные. Или если я открываю, блокирую, запишите и разблокируйте.

То, что произойдет файла, работается на, и другие данные должны быть записаны. Будет это действие быть потерянным, или будет это быть сохраненным. и если это будет сохраненным желанием, останов приложение.

Если Вы были, спасибо за чтение!

7
задан Joel Spolsky 2 March 2010 в 02:15
поделиться

7 ответов

У меня действительно есть высокопроизводительное многопоточное приложение, в котором все потоки записывают (добавляют) в один файл журнала. Пока не заметил никаких проблем с этим, каждый поток пишет несколько раз в секунду и ничего не теряется. Я думаю, что просто добавление к огромному файлу не должно быть проблемой. Но если вы хотите изменить уже существующий контент, особенно с параллелизмом - я бы пошел с блокировкой, иначе может случиться большой беспорядок ...

6
ответ дан 6 December 2019 в 10:49
поделиться

Вот простой пример, который подчеркивает опасность одновременных белых:

<?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

Это потому, что добавление файла является атомарным, только если :

  1. Вы делаете единственный вызов fwrite ()
  2. и что fwrite () меньше, чем PIPE_BUF (где-то около 1-4k)
  3. , и вы пишете в полностью совместимую с POSIX файловую систему

Если вы делаете более одного вызова fwrite во время добавления в журнал, или вы пишете больше, чем около 4к, все ставки отключены.

Теперь о том, имеет ли это значение: вы согласны с тем, что в вашем журнале есть несколько поврежденных строк при большой нагрузке? Честно говоря, в большинстве случаев это вполне приемлемо, и вы можете избежать накладных расходов, связанных с блокировкой файлов.

9
ответ дан 6 December 2019 в 10:49
поделиться

Если параллелизм является проблемой, вам действительно следует использовать базы данных.

4
ответ дан 6 December 2019 в 10:49
поделиться

Если вы просто пишете журналы, возможно, вам стоит взглянуть на функцию syslog, поскольку syslog предоставляет api. Вам также следует делегировать запись на выделенный сервер и делать работа в асинхронном манере?

1
ответ дан 6 December 2019 в 10:49
поделиться

Используйте flock ()

См. Этот вопрос

0
ответ дан 6 December 2019 в 10:49
поделиться

Если вам нужно просто добавлять данные, PHP должен быть в порядке с этим, так как файловая система должна позаботиться об одновременном добавлении.

-3
ответ дан 6 December 2019 в 10:49
поделиться

Это мои 2p.

Если по какой-то конкретной причине не требуется уникальный файл, я бы не стал добавлять все в огромный файл. Вместо этого я бы обернул файл по времени и размеру. Для этого можно определить пару параметров конфигурации (wrap_time и wrap_size).

Кроме того, я бы, вероятно, ввел некоторую буферизацию , чтобы избежать ожидания завершения операции записи.

Вероятно, PHP не самый адаптированный язык для такого рода операций, но это все еще возможно.

1
ответ дан 6 December 2019 в 10:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: