Безопасно ли направлять вывод нескольких параллельных процессов в один файл, используя >>?

Я делаю это следующим образом:

    Configuration conf = new Configuration();
    conf.set("fs.hdfs.impl",org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
    conf.set("fs.file.impl",org.apache.hadoop.fs.LocalFileSystem.class.getName());
    FileSystem  hdfs = FileSystem.get(URI.create("hdfs://<namenode-hostname>:<port>"), conf);
    hdfs.delete("/path/to/your/file", isRecursive);

вам не нужно hdfs://hdfshost:port/ в вашем пути к файлу

37
задан conradlee 22 January 2013 в 16:16
поделиться

7 ответов

Нет. Не гарантируется, что линии останутся нетронутыми. Они могут смешаться.

В результате поиска, основанного на ответе Лиори, я обнаружил это :

Запросы на запись размером {PIPE_BUF} байтов или меньше не должны чередоваться с данными других процессов, выполняющих запись в том же канале. При записи байтов, превышающих {PIPE_BUF}, данные могут чередоваться на произвольных границах с записями других процессов, независимо от того, установлен ли флаг O_NONBLOCK флагов состояния файла.

Таким образом, не гарантируется, что строки длиннее {PIPE_BUF} байтов останутся нетронутыми.

28
ответ дан 27 November 2019 в 04:48
поделиться

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

Если я пытаюсь выполнить захват из нескольких источников, гораздо проще (и легче отлаживать) иметь многофайловые «бумажные следы», и если мне нужен общий файл журнала, объединить его на основе метки времени (вы используют временные метки, верно?) или, как сказала Лиори, syslog.

3
ответ дан 27 November 2019 в 04:48
поделиться

Как правило, нет.

В Linux это возможно при соблюдении двух условий: каждая строка записывается за одну операцию, и длина строки не превышает PIPE_SIZE (обычно то же самое, что и PAGE_SIZE, обычно 4096). Но ... я бы не стал на это рассчитывать; это поведение может измениться.

Лучше использовать какой-нибудь реальный механизм ведения журнала, например syslog.

7
ответ дан 27 November 2019 в 04:48
поделиться

Используйте временные файлы и объединяйте их вместе. Это единственный безопасный способ сделать то, что вы хотите, и (вероятно) потеря производительности при этом будет незначительной. Если производительность действительно является проблемой, попробуйте убедиться, что каталог /tmp является файловой системой на базе оперативной памяти, и поместить туда временные файлы. Таким образом, временные файлы будут храниться в оперативной памяти, а не на жестком диске, поэтому их чтение/запись будет происходить практически мгновенно.

4
ответ дан 27 November 2019 в 04:48
поделиться

Вам нужно убедиться, что вы записываете целые строки в одиночных операциях записи (поэтому, если вы используете какую-либо форму stdio, вам нужно настроить его на буферизацию строк по крайней мере на длину самой длинной строки, которую вы можете вывести). Поскольку оболочка использует O_APPEND для >> перенаправления, все ваши записи будут автоматически добавляться в файл без каких-либо дополнительных действий с вашей стороны.

3
ответ дан 27 November 2019 в 04:48
поделиться

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

Подумайте об Apache2 с ведением журнала по конвейеру (с чем-то вроде распределения на другом конце канала, если вы настроены амбициозно). Это подход, который он использует, когда несколько потоков / процессов используют один процесс ведения журнала.

0
ответ дан 27 November 2019 в 04:48
поделиться

Вкратце, нет. >> не уважает несколько процессов.

1
ответ дан 27 November 2019 в 04:48
поделиться
Другие вопросы по тегам:

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