разделенный файл hadoop одинакового размера - PullRequest
4 голосов
/ 06 октября 2011

Я пытаюсь научиться разбивать файл, хранящийся в hdfs, на разделение и читать его в другой процесс (на разных машинах).

Я ожидаю, что у меня будет SequenceFile, содержащий 1200 записей с 12 процессамиЯ бы увидел около 100 записей на процесс.Чтобы разделить файл, нужно получить длину данных, затем разделить на количество процессов, получить размер фрагмента / начального / конечного размера для каждого разбиения, а затем передать это разбиение, например, SequenceFileRecordReader, извлекая записи в простом цикле while.Код указан ниже.

private InputSplit getSplit(int id) throws IOException {
...
    for(FileStatus file: status) {
        long len = file.getLen();
        BlockLocation[] locations =
            fs.getFileBlockLocations(file, 0, len);
        if (0 < len) {
            long chunk = len/n;
            long beg = (id*chunk)+(long)1;
            long end = (id)*chunk;
            if(n == (id+1)) end = len;
            return new FileSplit(file, beg, end, locations[locations.length-1].getHosts());
        } 
    }
...
}

Однако результат показывает, что сумма общих записей, подсчитываемых каждым процессом, отличается от записей, хранящихся в файле.Как правильно разделить SequenceFile на части и распределить их по разным хостам?

Спасибо.

1 Ответ

4 голосов
/ 09 октября 2011

Я не могу не задаться вопросом, почему вы пытаетесь сделать такую ​​вещь.Hadoop автоматически разделяет ваши файлы и 1200 записей, которые будут разделены на 100 записей, не похоже на большой объем данных.Если вы уточните, в чём ваша проблема, кто-то может помочь вам более напрямую.

Вот мои две идеи:


Вариант 1. Использование автоматического разделения Hadoop

Hadoop автоматически разбивает ваши файлы.Количество блоков, на которые разделен файл, - это общий размер файла, деленный на размер блока.По умолчанию одна задача карты будет назначена каждому блоку (не каждому файлу).

В вашем файле конфигурации conf/hdfs-site.xml есть параметр dfs.block.size.Большинство людей устанавливают это на 64 или 128 МБ.Однако, если вы пытаетесь сделать что-то крошечное, например, 100 записей файла последовательности на блок, вы можете установить это действительно низкое значение, скажем, 1000 байтов.Я никогда не слышал о том, чтобы кто-нибудь хотел это сделать, но это вариант.


Вариант 2. Использование задания MapReduce для разделения ваших данных.

Попросите вашу работу использовать «устройство отображения личности» (в основном реализуйте Mapper и не переопределяйте map).Кроме того, пусть ваша работа использует «редуктор идентификации» (в основном реализуйте Редуктор и не переопределяйте reduce).Установите количество редукторов на количество разделений, которое вы хотите иметь.Скажем, у вас есть три файла последовательности, которые вы хотите разделить на 25 файлов, вы должны загрузить эти 3 файла и установить число редукторов равным 25. Записи будут случайным образом отправляться каждому редуктору, и в итоге вы получите25 равных разбиений.

Это работает, потому что преобразователи и преобразователи идентичности фактически ничего не делают, поэтому ваши записи останутся прежними.Записи отправляются случайным редукторам, а затем записываются по одному файлу на редуктор в файлы part-r-xxxx.Каждый из этих файлов будет содержать ваши файлы последовательности, разделенные на несколько четных частей.

...