Использование сценария “разделяется” в цикле по большим файлам

Хм, если Вы соединяетесь от клиента на поле Kali Linux (gsd из меню Kali, или https://localhost:9390 в браузере), это должно просто работать (видео). Вы выполняете Kali 1.0.4? Я знаю, что они пострадали от поломки в OpenVAS в 1.0.3, но я верю 1.0.4, просто работал на меня первым выбором "openvas установка" из меню Kali, и затем "openvas запускают gsd"

3
04.08.2014, 15:53
2 ответа

Мне любопытно из вопроса решить проблему памяти с решением split, но независимо от этого, этот альтернативный подход может быть полезен:

Вы могли бы использовать csplit вместо split для разделения такого файла.

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

Мне не понятно, в чем проблема с памятью, но использование другого инструмента может с этим справиться.

Но есть и преимущество в том, что команда становится проще, нет необходимости сначала получать число.

Команда будет что-то вроде:

csplit --elide-empty-files -n4 in.txt '/^[0-9]\+$/' '{*}'

2
27.01.2020, 21:14

Дополнительное объяснение, основанное на производительности файловой системы NTFS

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

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

Таким образом, плохая производительность NTFS могла бы быть альтернативным объяснением снижения производительности, в то время как чрезмерное использование памяти, похоже, все еще связано с mmap ().

Плохая производительность NTFS
Настройка файловой системы NTFS для повышения производительности


Объяснение проблемы с памятью путем активного использования mmap ()

Проблема с памятью, которая возникает при split в вашем сценарии, кажется, связано с использованием mmap в 'split'.

strace показывает следующие вызовы для каждого выходного файла:

28892 open("xx02", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
28892 fstat(3, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
28892 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f821582f000
28892 write(3, "sometext\n", 30) = 30
28892 close(3)                          = 0
28892 munmap(0x7f821582f000, 4096)      = 0


Основываясь на примерах, для приблизительной оценки обрабатываемых файлов,
мы предполагаем, что входные файлы - 300 МБ, выходные файлы - 100Б:

Это дает нам около 3000000 файлов для записи. Пишем сразу только одну. Но мы используем mmap () . Это означает, что для каждого файла используется как минимум одна страница памяти размером 4096 Байт.

Принимая это во внимание, мы затрагиваем около 12 ГБ памяти (1) для одного входного файла (но не всех сразу). Три миллиона файлов и 12 ГБ звучат так, как будто это может вызвать некоторую работу для ядра.

По сути, похоже, что split просто не предназначен для этого задания , потому что он использует mmap () .
Это хорошо в других ситуациях.
Но в этом крайнем случае ввода это сильно испортит управление памятью, и тогда потребуется некоторое время для очистки. (2)

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

(1) Или только адресное пространство?

4
27.01.2020, 21:14

Теги

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