Сортировка файла 1TB на машине с ОЗУ 1GB

эти вопросы кажутся легкими, но я не могу понять реальную работу за ним. Я знаю, что люди скажут, разбиваются на 512 мегабайт и сортируют их, как с помощью сортировки слиянием с помощью Map reduce.

Так вот собственно вопрос у меня есть:

предположим, я разбиваю файл на 512 мегабайт, а затем отправляю на разные хост-машины для их сортировки. предположим, эти машины использовали сортировку слиянием. Теперь скажем, у меня было 2000 машин, каждая сортировала 2000, 512 мегабайт куска. Теперь, когда я сливаю их обратно, как это работает? Не будет ли размер снова увеличиваться? Например, слияние двух 512 мегабайт сделает 1024Megs, который является размером моего ОЗУ, так как это будет работать? Любая машина не может объединить кусок более 512 мегабайт с другим куском, потому что тогда размер > 1 ГБ.

Как в конце слияния я когда-либо смогу объединить два куска 0.5 TB с другим куском 0.5 TB.. Вступает ли здесь в игру концепция виртуальной памяти?

Я здесь, чтобы прояснить мое основы и я надеюсь, что я задаю этот очень важный вопрос (Правильно) правильно. Кроме того, кто должен сделать это слияние(после сортировки)? Моя машина или несколько из этих 2000 машин?

5 ответов


вот теоретический способ, который должен работать. Скажем, у вас есть файлы 2000 512mb, готовые к созданию одного файла 1TB.

Если вы просто перебираете каждый файл, находите, какой из них имеет самое низкое первое значение, затем перемещаете его в файл назначения и повторяете, то вы получите все в порядке. Использование ОЗУ должно быть крошечным, так как вам никогда не придется открывать более одной строки за раз.

очевидно, вы должны иметь возможность оптимизировать это-сохранить первую строку каждого файл в ОЗУ, как вы идете, и он должен быть несколько быстрее.


краткая версия того, как вы сливаетесь, выглядит так:

1) вы создаете таблицу с одним слотом для каждой машины, с которой вы объединяетесь.

2) вы спрашиваете у каждой машины самую низкую запись, которую они еще не дали вам.

3) вы удаляете самую низкую запись из своей таблицы, выводите ее и просите эту машину пополнить медленную самую низкую запись, которую она еще не дала вам, оставляя слот пустым, если машина вышла из вступления.

4) Вы повторяете Шаг 3, пока таблица не опустеет.

Это позволяет объединить из N машин, хранящих только N записей одновременно. Конечно, вы можете тривиально оптимизировать его для хранения M записей с каждой машины. В этом случае вам нужно сохранить N*M записей, и когда слот пуст, попросите эту машину для M записей, чтобы пополнить его.


теперь скажем, у меня было 2000 машин, каждая сортировала 2000, 512 мегабайт куска. Сейчас когда я объединяю их обратно, как это работает? Не размер продолжай снова увеличивается? Например, слияние двух 512 мегабайт составит 1024Megs какой размер моей ОЗУ, так как это будет работать? Любая машина не может объедините кусок более 512 мегабайт с другим куском, потому что затем размер > 1 ГБ.

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

другими словами, вам не нужен случайный доступ для mergesort. Если бы не это хорошее свойство, было бы невозможно сортировка данных на ленточных накопителях С технологией доступной в то время. Ленточные накопители, конечно не носители произвольного доступа и ОЗУ тогда измерялись в килобайтах.


эта проблема может быть сводится к более простой проблеме. Эта проблема была разработана, чтобы заставить вас подход. Вот это:

  • Pick Up chunks =~ 1GB, сортировать и хранить их в виде отдельных отсортированных файлов.
  • вы получаете 1000 1GB отсортированных файлов в файловой системе.
  • теперь это просто проблема слияния K-отсортированных массивов в новый массив.

    слияние K-отсортированных массивов необходимо поддерживать минимальную кучу (очередь приоритетов) с k элементов одновременно.

то есть k = 1000 (файлов) в нашем случае. ( 1 ГБ ОЗУ может хранить 1000 номеров )

таким образом, сохранить всплывающие элементы из очереди приоритетов и сохранить на диск.

У вас будет новый файл, отсортированный по размеру 1 ТБ.

см.: http://www.geeksforgeeks.org/merge-k-sorted-arrays/

обновление

PS: может быть сделано на одной машине с 1 ГБ оперативной памяти с лучшей структурой данных

слияние может быть сделано менее чем O (N) space С очередью приоритетов, т. е. O (K) space т. е. суть проблемы.


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

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