Нужна высокая производительность / бин / сортировка; какие-либо предложения?

Я ищу замену высокой производительности / bin / sort. Я знаю, что есть pbzip2 для использования нескольких ядер, но есть ли аналогичный продукт для / bin / sort?

Я нашел distsort.sh, но я хочу что-то менее интенсивное IO. Я ищу сортировку о.. 60 концертов данных на очень частой основе.

4 ответа

Решение

GNU sort имеет -m, который может вам помочь. Предположим, у вас есть 200 .gz-файлов, которые вы хотите отсортировать и объединить. Тогда вы можете использовать GNU Parallel, чтобы сделать:

seq 1 200 | parallel mkfifo /tmp/{}
ls *.gz | nice parallel -j200 'zcat {} | sort >/tmp/$PARALLEL_SEQ' &
seq 1 200 | parallel -X sort -m /tmp/{} >/tmp/sorted

Если проблема связана с вводом / выводом, а память не является проблемой, используйте -S для первого sort чтобы убедиться, что все остается в памяти. Также вы можете использовать lzop каждый раз, когда вы пишете на диск (--compress-program=lzop): Диски часто являются ограничивающим фактором, поэтому lzopping на лету может дать вам дополнительную скорость. Или вы можете создать RAM-диск и установить -T в этот каталог.

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

Nsort - это программа сортировки / слияния, которая может быстро сортировать большие объемы данных, используя большое количество процессоров и дисков параллельно. Nsort - единственная коммерческая программа сортировки, которая демонстрирует:

  • 1 терабайт сортирует (33 минуты)
  • Скорость чтения и записи файла 1 гигабайт / с

Nsort имеет долгую историю сортировки массивных производственных наборов данных, таких как:

  • Веб-журналы для веб-сайтов с большим трафиком
  • Журналы телефона
  • Данные государственного агентства

Хмм. Я думаю, вы столкнетесь здесь с несколькими проблемами. Прежде всего, ваши входные данные окажут большое влияние на производительность сортировки (различные алгоритмы работают лучше или хуже в зависимости от распределения входных данных). Однако большая проблема заключается в том, что 60 ГБ - это много данных.

Кроме того, сортировка не может паралеллизировать так же легко, как сжатие, потому что нет гарантий близости. Другими словами, с помощью сжатия / распаковки вы можете разбить входные данные на отдельные фрагменты и работать с ними по отдельности и независимо. После обработки каждого куска они просто соединяются вместе. С сортировкой у вас есть несколько шагов, потому что вы не можете просто объединить результаты (если вы не выполняете некоторую предварительную обработку), вы должны объединить результаты (потому что запись в начале 60 ГБ может оказаться рядом с записью в конце 60гб, после сортировки).

Я могу в основном подумать о нескольких общих решениях здесь:

  • Подготовьте данные таким образом, чтобы они были удобны для сортировки и объединения. Например, если вы выполняли простую алфавитную сортировку, вы можете хранить свои данные в 26 сегментах, по одному на каждую букву алфавита. Затем вы можете отсортировать каждое ведро по отдельности и в конце рекомбинировать их. Специфика того, как вы подготовили свои данные, будет зависеть от самих данных, вашего текущего метода хранения и т. Д. Некоторые настройки могут работать лучше для этого, чем другие.
  • Напишите свой собственный вид сортировки, который делает в основном то, о чем я писал выше, но на лету. Другими словами, у вас будет скрипт, который читает входные данные и основывается на какой-то очень быстрой операции (такой как чтение первой буквы или что-то еще, что работает с вашими данными), а затем распределяет этот фрагмент данных в соответствующую корзину сортировки. Каждый вид работает независимо, пока все данные не будут обработаны, затем вы объединяете их все вместе. На самом деле это очень похоже на особый случай использования MapReduce для сортировки.
  • Используйте решение для сортировки на основе MapReduce. Существует проект с открытым исходным кодом под названием Hadoop, который предоставляет несколько подпроектов, одним из которых является реализация Open Source MapReduce. Я никогда не использовал это, однако, только прочитал об этом. Я понятия не имею, будет ли это практически применимо к вашей конкретной проблеме.
  • Можете ли вы проиндексировать данные, а затем просто отсортировать их? Являются ли все 60 ГБ частью ключа сортировки? Или есть меньшая часть, по которой вы сортируете, а затем куча дополнительных данных для каждой части? Если это последнее, индексация и сортировка просто какого-то значения ключа, а затем поиск дополнительных данных по мере необходимости, может быть способом.
  • Возможно, вы могли бы полностью предварительно отсортировать данные и сохранить их в отсортированном состоянии. Каждый раз, когда вы добавляете или обновляете данные, вы исправляете их с упорядоченной точки зрения. Это решение будет в значительной степени зависеть как от того, как вы храните свои данные, так и от того, будет ли влияние на производительность обновлений сортировки приемлемым.
  • Наконец, вы могли бы поносить все это. Сбросьте ваши данные в СУБД (мне сам нравится PostgresSQL), и пусть база данных обработает вашу сортировку для вас.

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

[Примечание: я не специалист по сортировке, поэтому кто-то умнее меня может указать на ошибки в моей логике или предложения по их исправлению.]

Perl?

Редактировать: Ну, эта статья о Perl-сортировке Perf Tunning. Из того, что я могу понять из этого, это в основном больше руководство по лучшей практике, сравнивающее, как плохой код сортировки может сделать вашу программу очень медленной, и наоборот, как сделать это быстрее.

Небрежное программирование, небрежное исполнение.

Другие вопросы по тегам