Распределенные чтения HDFS без Map / Reduce - PullRequest
6 голосов
/ 10 декабря 2011

Можно ли добиться распределенного чтения из кластера HDSF с использованием клиента HDFS на одной машине?

Я провел эксперимент с кластером, состоящим из 3 узлов данных (DN1, DN2, DN3).Затем я запускаю 10 одновременных операций чтения из 10 независимых файлов из клиентской программы, расположенной на DN1, и она, кажется, считывает данные только с DN1.Другие узлы данных (DN2, DN3) демонстрировали нулевую активность (судя по журналам отладки).

Я проверил, что блоки всех файлов реплицированы на все 3 узла данных, поэтому, если я выключаю DN1, тогда данные считываются с DN2 (только DN2).

Увеличение объема считываемых данныхне помогло (пробовал от 2ГБ до 30ГБ).

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

Я использую SequenceFile для чтения / записи данных, таким образом (jdk7):

//Run in thread pool on multiple files simultaneously

List<String> result = new ArrayList<>();
LongWritable key = new LongWritable();
Text value = new Text();
try(SequenceFile.Reader reader = new SequenceFile.Reader(conf,
                                     SequenceFile.Reader.file(filePath)){
  reader.next(key);
  if(key.get() == ID_I_AM_LOOKING_FOR){
    reader.getCurrentValue(value);
    result.add(value.toString());
  }
}

return result; //results from multiple workers are merged later

Любая помощь приветствуется.Спасибо!

Ответы [ 3 ]

7 голосов
/ 10 декабря 2011

Я боюсь, что поведение, которое вы видите, является неконструктивным. Из документа Hadoop :

Выбор реплики

Чтобы минимизировать потребление глобальной полосы пропускания и задержку чтения, HDFS пытается удовлетворить запрос на чтение из реплики, ближайшей к читатель. Если существует реплика в той же стойке, что и узел считывателя, тогда эта реплика предпочтительнее для удовлетворения запроса на чтение. Если ангг / Кластер HDFS охватывает несколько центров обработки данных, а затем реплику, которая резидент в местном центре обработки данных предпочтительнее любого удаленного копия.

Это может быть дополнительно подтверждено соответствующим исходным кодом Hadoop :

  LocatedBlocks getBlockLocations(...) {
    LocatedBlocks blocks = getBlockLocations(src, offset, length, true, true);
    if (blocks != null) {
      //sort the blocks
      DatanodeDescriptor client = host2DataNodeMap.getDatanodeByHost(
          clientMachine);
      for (LocatedBlock b : blocks.getLocatedBlocks()) {
        clusterMap.pseudoSortByDistance(client, b.getLocations());

        // Move decommissioned datanodes to the bottom
        Arrays.sort(b.getLocations(), DFSUtil.DECOM_COMPARATOR);
      }
    }
    return blocks;
  }

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

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

3 голосов
/ 10 декабря 2011

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

Есливы работаете с меньшими наборами данных, возможно, вы захотите взглянуть на HBase, который позволяет работать с более мелкими порциями и распределять нагрузку между узлами (путем разделения областей)

0 голосов
/ 11 декабря 2011

Я бы сказал, что ваш случай звучит хорошо для MR.Если мы оставим в стороне определенную вычислительную парадигму MR, мы можем сказать, что hadoop построен для того, чтобы принести код в данные, а не наоборот.Перемещение кода в данные необходимо для масштабируемой обработки данных.
С другой стороны - настройка MapReduce проще, чем HDFS - поскольку он не хранит состояния между заданиями.
В то же время - среда MR будет заботиться о параллельной обработке для вас - что потребует времени для правильной работы.
Еще один момент - если результаты обработки данных настолько малы - не будет существенного влияния на производительность, если вы объедините их вместе в редуктор.
Другими словами - я бы предложил пересмотреть использование MapReduce.

...