Какие сильные и слабые стороны у HDFS?

«Какие сильные и слабые стороны у HDFS?» — вопрос из категории Hadoop и HDFS, который задают на 33% собеседований Data Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Сильные стороны:

  • Масштабируемость: Архитектура позволяет линейно масштабироваться до тысяч узлов и хранить петабайты данных.
  • Отказоустойчивость: Репликация блоков данных (по умолчанию 3 копии) обеспечивает защиту от сбоев железа.
  • Экономичность: Работает на стандартном, относительно дешевом оборудовании (commodity hardware).
  • Оптимизация для больших данных: Эффективен для последовательной обработки больших файлов, что идеально для парадигм вроде MapReduce.

Слабые стороны:

  • Плохая работа с малыми файлами: Каждый файл, блок и его репликация создают запись в памяти NameNode, что становится узким местом.
  • Высокая задержка доступа: Не предназначен для интерактивных запросов с низкой латентностью или OLTP-нагрузки.
  • Сложность операций записи: Модель "write-once-read-many" не позволяет изменять файлы после создания, только дописывать (append) или полностью перезаписывать.
  • Администрирование: Требует настройки и мониторинга балансировки кластера, репликации, работы с отказавшими узлами.

Пример решения проблемы малых файлов: Вместо загрузки тысяч маленьких файлов, их можно объединить в один файл формата SequenceFile или HAR (Hadoop Archive).

// Пример создания SequenceFile из множества мелких текстовых файлов
Configuration conf = new Configuration();
Path inputPath = new Path("/input/small_files");
Path outputPath = new Path("/output/merged.seq");

FileSystem fs = FileSystem.get(conf);
SequenceFile.Writer writer = SequenceFile.createWriter(conf,
        Writer.file(outputPath),
        Writer.keyClass(Text.class),
        Writer.valueClass(Text.class));

RemoteIterator<LocatedFileStatus> it = fs.listFiles(inputPath, false);
while (it.hasNext()) {
    LocatedFileStatus fileStatus = it.next();
    if (!fileStatus.isFile()) continue;
    Text key = new Text(fileStatus.getPath().getName());
    Text value = new Text();
    // ... чтение содержимого файла в value
    writer.append(key, value);
}
writer.close();