Масштабируемость sort -u для гигантских файлов

23

Каков разумный предел масштабируемости для 'sort -u'? (в измерениях «длина строки», «количество строк», «общий размер файла»?)

Что является альтернативой Unix для файлов, превышающих это в измерении «количества строк»? (Конечно, я могу легко реализовать один, но я задавался вопросом, можно ли что-то сделать с помощью нескольких стандартных команд Linux?)

Гжегож Вежовецкий
источник
Для тех, кто захочет выполнить бинарный поиск или узнать, как это сделать: unix.stackexchange.com/q/247508/9689
Гжегож Вежовецкий,
2
Есть ситуации, когда uniqперед тем sort -uпомогает. Кстати, данные ASCII очень сильно LC_ALL=C sortsort
ускоряют

Ответы:

39

То, sortчто вы найдете в Linux, происходит из пакета coreutils и реализует слияние с внешним R-Way . Он разбивает данные на куски, которые он может обрабатывать в памяти, сохраняет их на диске и затем объединяет. Куски выполняются параллельно, если на машине есть процессоры для этого.

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

Энтон
источник
3
Обратите внимание, что сортировка GNU может сжимать эти временные файлы, чтобы упаковать их еще больше (и повысить производительность на медленных дисках).
Стефан Шазелас
1
@ StéphaneChazelas Спасибо за обновление. Я задавался вопросом, достаточно ли умна сортировка для удаления фрагментированных файлов, когда они полностью объединены (что может легко случиться, если источник уже частично отсортирован) в качестве оптимизации пространства. У меня нет времени, чтобы погрузиться в исходный код в эти дни :-(
Anthon
3
Помимо памяти, есть еще один предел, который применяется к фазе слияния: количество файлов, которые могут быть одновременно открыты. Обычно это ограничение, налагаемое операционной системой. GNU sort также справляется с этим, рекурсивно объединяя количество файлов, которые он может открыть за один раз!
Диомидис Спинеллис
@ StéphaneChazelas Если бы я разрабатывал инструмент специально для сортировки очень больших файлов, я бы сохранял строки в виде индекса в исходном файле. Делает ли это сортировка GNU или просто использует обычный алгоритм сжатия?
Random832
3
@ Random832, и он предназначен для того, чтобы иметь возможность перезаписывать файл поверх самого себя ( sort -o file file)
Стефан Шазелас
1

Я не могу говорить о конкретных реализациях поставщика, но UNIX sortреализация разбивает большие файлы на более мелкие, сортирует эти файлы и затем объединяет отсортированные меньшие файлы в агрегированный отсортированный вывод.

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

Шили
источник
3
Что именно вы называете реализацией сортировки UNIX ? Это оригинал из Unix версии 3? На странице руководства сказано, что он не может сортировать файлы размером более 128 КБ.
Стефан Шазелас
Что вы понимаете под Unix версии 3? Версия от 1973 года? Исходная реализация сортировки UNIX была улучшена за эти годы, и IIRC, версия Solaris, даже намного быстрее, чем версия GNU. Конечно, 25 лет назад сортировка была улучшена для понимания многобайтовых символов, и что я помню из обсуждения USENET, это то, что это было эффективно сделано в Solaris. Кстати: man largefileсписок sortкак большой файл осведомлен.
Шили
2
Так вы на самом деле говорите о конкретной версии Oracle для вендора sort? Или какая-нибудь производная от какой-то версии AT & T Unix? Или какая-нибудь Unix-сертифицированная версия sort(например, GNU sortна OS / X)?
Стефан Шазелас
Качество современных sortреализаций в отношении многобайтовых символов может различаться, тот факт, что sortиспользуются разделенные промежуточные файлы, является общим для всех реализаций UNIX, основанных на исходном коде. КСТАТИ: версия Solaris является ОСС как «OpenSolaris», см sourceforge.net/p/schillix-on/schillix-on/ci/default/tree/usr/...
Шили
25 лет назад UTF-8 еще не был изобретен? Поддержка локалей UTF-8 была добавлена ​​в Solaris 7 ( 1 , 2 ). Вы имеете в виду какой-то другой многобайтовый набор символов?
Стефан Шазелас
1

На основании https://blog.mafr.de/2010/05/23/sorting-large-files/ и /unix//a/88704/9689 :

split -n l/20 input input-
for inpf in input-* ; do
    sort --parallel="$(nproc --all)" "${inpf}" > sorted-"{$inpf}"
done
sort -m sorted-input-* > sorted-input

Обновить:

Из ответов выше мы видим, что sortуже делает то, что упомянул фрагмент - т.е. слияние внешнего R-Way . Так ведь работает всего лишь:

sort --parallel="$(nproc --all)" -u input > output

Должно быть достаточно.

Мои текущие предположения (без проверки кода) об ограничениях:

  • Максимальная длина строки ограничена объемом физической памяти. Сортировать нужно вписать как минимум две в память
  • количество строк - я не в курсе
  • размер файла - конечно, по файловой системе
  • количество открытых файлов параллельно - в зависимости от операционной системы (спасибо Diomidis Spinellis за то, что указал на это!)

(Этот ответ помечен как вики сообщества - чувствую себя лучше, чтобы улучшить его! :))

оборота Гжегож Вежовецки
источник
2
GNU sortсортирует параллельно по умолчанию (начиная с 2010 года после того, как страница, на которую вы ссылаетесь), --parallelнеобходимо уменьшить количество одновременных потоков, вместо того, чтобы sortопределять оптимальный. Сортировка уже делает разбиение и слияние внутри более эффективным способом. Я сомневаюсь, что дополнительное разделение поможет.
Стефан Шазелас