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

Ответ

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

  • Масштабируемость: Архитектура позволяет линейно масштабироваться до тысяч узлов и хранить петабайты данных.
  • Отказоустойчивость: Репликация блоков данных (по умолчанию 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();

Ответ 18+ 🔞

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

Что у неё хорошо получается, так это размах. Архитектура у неё такая, что можно наращивать кластер до овердохуища узлов и хранить там петабайты всего. Это не шутки. И если какой-то сервак накрылся медным тазом — да похуй, потому что данные реплицируются (по умолчанию в трёх экземплярах). Стоит всё это на обычном, недорогом железе, что для бизнеса — просто песня. И заточена она под последовательную обработку здоровенных файлов, что для всяких MapReduce — самое то.

А теперь про слабые места, их тоже хватает. Первое и главное — она ненавидит мелкие файлы. Представь: каждый файлик, даже размером с пиксель, — это запись в памяти главного узла (NameNode). Загрузишь туда миллион фоток с котиками — и всё, NameNode просто ебанько, памяти не хватит, и кластер встанет. Это её ахиллесова пята, хуй с горы. Второе — она медленная для интерактива. Ждать от неё ответа за миллисекунды — это как требовать от того же грузовика скорости спорткара. Доверия ебать ноль в таких сценариях. Запись — тоже не сахар. Модель «записал один раз — читай сколько влезет» не позволяет просто взять и отредактировать кусочек в середине файла. Только дописать в конец или переписать всё целиком. И да, админить эту банду — нужно следить за балансировкой, репликацией, отвалившимися узлами... Терпения ноль ебать иногда.

Как решить проблему с мелкими файлами? Не надо их туда пихать как есть! Нужно делать как умные люди — пачку мелких файлов упаковывать в один большой, например, в 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();

Короче, хитрая жопа эта HDFS. Мощная, но со своими тараканами. Главное — понимать, для чего она, а не пытаться впихнуть невпихуемое.