Hadoop Flashcards

1
Q

Расскажи про архитектуру Hadoop? #Ярослав #wildberries

A

o Основные компоненты: HDFS (хранилище) и YARN (менеджер ресурсов).
o В HDFS – NameNode управляет метаданными, DataNode хранят блоки.
o YARN координирует запуск задач (ResourceManager) и управление контейнерами (NodeManager).
o MapReduce – фреймворк для параллельной обработки данных поверх YARN.

NameNode
* Обязательный компонент кластера HDFS, который отвечает за
открытие и закрытие файлов, создание и удаление каталогов, управление
доступом со стороны внешних клиентов и соответствие между файлами и
блоками, дублированными (реплицированными) на узлах данных. Сервер
имён раскрывает для всех желающих расположение блоков данных на
машинах кластера
* Хранит метаданные о структуре файловой системы: информацию о файлах, блоках, их расположении на DataNodes и структуру каталогов.
* единственный в кластере, сервер с программным кодом для управления
пространством имен файловой системы, хранящий дерево файлов, а также
мета-данные файлов и каталогов.

DataNode
Это один их множества серверов кластера с программным кодом, отвечающим за файловые операции и работу с блоками данных. DataNode – обязательный компонент кластера HDFS, который отвечает за запись и чтение данных, выполнение команд от узла NameNode по созданию, удалению и репликации блоков, а также периодическую отправку сообщения о состоянии (heartbeats) и обработку запросов на чтение и запись, поступающих от клиентов файловой системы HDFS. Стоит отметить, что данные проходят с остальных узлов кластера к клиенту мимо узла NameNode
* Узлы хранения данных.
* Хранят блоки данных и отвечают за операции записи и чтения по запросу от клиентов или NameNode.
* Регулярно отсылают информацию о состоянии блоков в NameNode для мониторинга целостности и доступности данных.

ResourceManager
Это планировщик ресурсов, абстрагирующий все вычислительные ресурсы кластера и управляющий их предоставлением. Для выполнения заданий оперирует понятием Container (контейнер). Resource Manager: принимает задание от Client, смотрит на доступные ресурсы и выбирает сервер, на котором есть доступные ресурсы, запускает на сервере Application Master (главный координатор того, как выполняется задание, следит, чтобы оно выполнялось корректно) и передаёт ему задание, выделяет по запросу Application Master контейнеры с ресурсами.
* Центральный узел управления ресурсами для YARN.
* Принимает запросы от ApplicationMaster и выделяет контейнеры с ресурсами на узлах для выполнения задач.
* Состоит из Scheduler и Application Manager, которые управляют выделением ресурсов и мониторингом приложений.

NodeManager
Это (менеджер узлов) — это подчинённый процесс, работающий на каждом узле и отвечающий за запуск контейнеров приложений (Container), мониторинг использования ресурсов контейнера (Application Master): процессор, память, диск, сеть, и передачу этих данных Resource Manager. Application Master: запрашивает у Resource Manager ресурсы для выполнения заданий, взаимодействует с контейнером
* Агент на каждом рабочем узле, который управляет ресурсами (процессор, память) для YARN.
* Запускает контейнеры по запросу от ResourceManager и контролирует их выполнение.
* Обеспечивает мониторинг состояния ресурсов на узле и отправляет отчёты ResourceManager.

ApplicationMaster
* Создаётся для каждого приложения, запускаемого на YARN.
* Управляет выполнением конкретного приложения (например, MapReduce или Spark), запрашивая ресурсы у
* Координирует выполнение задач и следит за прогрессом приложения.

Secondary NameNode
* вторичный узел имен, отдельный сервер,
единственный в кластере, который копирует образ HDFS и лог транзакций
операций с файловыми блоками во временную папку, применяет изменения,
накопленные в логе транзакций к образу HDFS, а также записывает его на
узел NameNode и очищает лог транзакций.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Кейс: вставляем кучу строк по одной (одну процессим и сразу вставляем, и так для каждой) в Hadoop – какая тут может возникнуть проблема? как избежать? #wildberries

A

Отвечу подробно и фактологически точно, как ты попросил.
Кейс: построчная вставка данных в Hadoop (любую таблицу — Hive, HDFS-файлы, HBase, Kudu и т.д.). Ты уточнил, что строки обрабатываются и вставляются по одной, не батчами.

Основные проблемы построчной вставки в Hadoop:

  1. Невероятно высокая нагрузка на метаданные и файловую систему
    • В HDFS (или в HDFS-совместимых хранилищах вроде Hive на ORC/Parquet) каждое создание файла или блоков метаданных — это отдельная операция для NameNode.
    • Если строки вставляются по одной и каждая ведет к новому файлу или новому блоку, то возникает эффект “small files problem” — тысячи/миллионы мелких файлов, каждый требует записи в память NameNode.
    • Факт: NameNode хранит все метаданные файлов в оперативной памяти. Чем больше файлов, тем выше риск “убить” NameNode по памяти или по скорости обработки RPC-запросов.
  2. Чудовищная неэффективность ввода-вывода (I/O)
    • HDFS оптимизирован под крупные записи (минимально 64 МБ блоки по умолчанию, чаще 128–256 МБ).
    • Построчная вставка ведет к постоянному созданию мелких блоков, что:
      • Растягивает время записи,
      • Сильно снижает пропускную способность,
      • Приводит к большому количеству дисковых seek’ов.
  3. Перегрузка транзакционной системы Hive / ACID DeltaLog
    • Если у тебя таблица на Hive с ACID, то каждая вставка создаёт отдельную транзакцию (insert) — высокая нагрузка на transaction manager (TxnManager).
    • Большое количество мелких коммитов тормозит систему из-за постоянного логирования, блокировок и роста размера файла-лога транзакций (delta файлов).
    • Могут появиться ошибки вида “too many open transactions” или “compaction backlog”.

Прием | Где буферизовать | Когда вставлять | Как вставлять |

  1. Бафферизация строк в приложении перед записью

Где копить:
- Локально в оперативной памяти процесса, который обрабатывает строки.
- Использовать массивы / очереди в коде (например, List или Queue в Java, list в Python).
- Порог накопления:
- По количеству строк (например, 10 000),
- ИЛИ по объему (например, 64–128 МБ по оценке объема объектов в памяти).

Как технически реализовать:

На Java/Scala:

```java
List<Row> buffer = new ArrayList<>();
for (Row row : incomingStream) {
buffer.add(row);
if (buffer.size() >= 10000) {
writeBufferToHive(buffer); // Вставка пачкой
buffer.clear();
}
}
~~~</Row>

Метод writeBufferToHive() должен:
- Либо собрать INSERT INTO table VALUES (...), (...), (...) (bulk insert),
- Либо сохранить данные в файл и сделать LOAD DATA.

На Python (например, для Spark):

```python
buffer = []
for row in incoming_stream:
buffer.append(row)
if len(buffer) >= 10000:
spark.createDataFrame(buffer).write.insertInto(“your_table”, overwrite=False)
buffer.clear()
~~~

  1. Использовать промежуточные файлы в HDFS

Что делать:

  • При накоплении достаточного объема данных (например, 128 МБ):
    • Писать их сначала в локальный файл (CSV, ORC, Parquet),
    • Затем перемещать файл в HDFS (через hdfs dfs -put или через API),
    • Потом делать LOAD DATA INPATH в Hive.

Пример пайплайна:

  1. В приложении строчки накапливаются в буфер.
  2. По достижении лимита:
    • Сериализовать их в локальный файл (например, .parquet).
  3. Через API:

```bash
hdfs dfs -put /local/file.parquet /user/hive/warehouse/tmp_load/
~~~

  1. Затем в Hive:

```sql
LOAD DATA INPATH ‘/user/hive/warehouse/tmp_load/file.parquet’ INTO TABLE target_table;
~~~

Или если таблица External — просто “положил” файл в каталог и обновил метаданные.

  1. Архитектурное решение: микробатчинг через стриминговые фреймворки

  • Использовать Apache Flink / Spark Structured Streaming:
    • Поступающие события группируются в батчи по времени (trigger=1 minute) или по количеству (batchSize=5000).
    • Затем одним батчем отправляются в систему хранения.

На практике:

```python
query = incomingStream \
.writeStream \
.trigger(processingTime=’1 minute’) \
.foreachBatch(write_to_hive) \
.start()
~~~

Где write_to_hive(batch_df, batch_id) пишет целый DataFrame за раз.

⚡ Итого: Как избежать проблем:

|:—————————–|:———————————-|:—————————–|:——————————–|
| В оперативной памяти | В списке (ArrayList, list, очередь) | После N строк или MБ данных | bulk insert или через файлы |
| В файловой системе | Во временных файлах | После достижения объема | LOAD DATA INPATH |
| Через API стриминга | В фреймворке (Flink/Spark) | По таймеру или по объему | foreachBatch / Streaming API |

Хочешь, дополнительно еще разберу:

  • Конкретные цифры лимитов для каждого способа (например, сколько строк копить в памяти, сколько в файле),
  • Ошибки, которые могут возникать при каждой стратегии (например, “too many open files”),
  • Как оценивать память для буферизации?

Хочешь, добью еще глубже? 🚀
Спросишь — сразу сделаю.

Нетривиальные кейсы/подводные камни:

  • Писать в одну таблицу одновременно несколькими процессами при мелких вставках может привести к race conditions или deadlocks в Hive ACID. Требуется либо распределение по партициям, либо через staging areas.
  • Разные партиции: если ты построчно вставляешь данные в разные партиции (например, по дате), нагрузка ещё возрастает (пересоздание партиционных метаданных).
  • Delta Lake (если используется): там частые маленькие записи создают взрыв количества файлов в storage (s3/hdfs) и требуют настройки optimize, vacuum.
  • HBase вставка по одной строке выглядит нормально (Put), но при нагрузке в миллионы сообщений требует ручного контроля памяти буфера (writeBufferSize) и размеров WAL.

Конкретный вывод для твоего кейса (по опыту WB и других крупных систем):

  • Писать по одной строке напрямую в Hadoop = гарантированный путь к деградации всей системы через пару часов.
  • Минимальная порция записи в Hadoop’оподобные системы должна быть хотя бы в десятки мегабайт или тысячи строк.
  • Всегда используй буферизацию, staging-объекты или файловую загрузку.

Хочешь, я ещё конкретно для твоего варианта (например, если скажешь Hive, HBase или Parquet в HDFS) распишу пошаговый оптимальный способ записи с кодом?
Тебе в каком контексте сейчас нужно: стриминг/онлайн или батч-процессинг?

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Что такое Yarn? #wildberries Астон

A

YARN (Yet Another Resource Negotiator)YARN управляет распределением ресурсов в кластере и выполняет задачи по управлению и планированию вычислительных процессов.

ResourceManager

Централизованный компонент, управляющий ресурсами кластера.

Назначает ресурсы приложениям.

Запускает ApplicationMaster для каждого приложения.

Следит за общим состоянием кластера.

NodeManager

Компонент, работающий на каждом узле (в том числе DataNode).

Получает команды от ResourceManager и ApplicationMaster.

Запускает контейнеры (процессы задач).

Мониторит использование ресурсов (CPU, RAM) на узле.

Отчитывается перед ResourceManager.

ApplicationMaster

Локальный координатор для конкретного приложения.

Запускается в отдельном контейнере.

Запрашивает ресурсы у ResourceManager.

Назначает задачи на контейнеры через NodeManager'ов.

Следит за выполнением и завершением приложения.

📌 Важно:
NodeManager выполняет задачи, но не управляет логикой приложения.
ApplicationMaster координирует и управляет всем процессом выполнения приложения в рамках YARN.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Какая структура у HDFS? #Cian #Ярослав

A
  • NameNode — «головной узел» (master), хранит метаданные о всех файлах и блоках (где какой блок находится). Без NameNode работа HDFS невозможна, так как именно он управляет файловой системой.
    2. DataNode — «рабочие узлы», на которых физически лежат блоки данных. Каждый блок файла может реплицироваться на несколько DataNodes (по умолчанию репликация = 3).
    3. Secondary NameNode или Checkpoint Node — вспомогательная служба, которая периодически объединяет журналы транзакций NameNode и снапшоты (FSImage), чтобы NameNode не распухал. (В современных кластерах могут использоваться HA-NameNode, JournalNode и т.д.)

Как всё устроено:
* Файл в HDFS делится на блоки (обычно 128 МБ). Каждый блок распределён по DataNodes.
* NameNode хранит только информацию о том, какой файл, какие у него блоки и где эти блоки лежат.
* При чтении/записи клиент запрашивает у NameNode список DataNode и взаимодействует с ними напрямую (NameNode не гоняет «полный» поток данных).

  • Итог: HDFS — это распределённая файловая система, где метаданные держит один координатор (NameNode), а данные рассыпаются на несколько DataNodes в виде блоков. Это даёт масштабирование и отказоустойчивость (при условии репликации).
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Проблема маленьких файлов в HDFS какая и как лечить? Как автоматизировать решения проблемы мелких файлов в Hadoop? #Cian #Иннотех #мир

A

Подробный ответ на вопрос «Проблема мелких файлов в HDFS и как её решить»

Что такое «мелкий файл» и почему именно это боль
1. Архитектура HDFS. С точки зрения NameNode любой файл — это метаданные: информация о блоках, репликации, правах. Память на файле-системе тратится не на данные, а на записи в оперативке NameNode (≈ 150–250 байт на блок + Java-объекты). Блок по умолчанию — 128 МБ, сервисы же часто стримят файлики по 2–10 КБ. Миллионы файлов → миллионы блоков. 4 ТБ в форма-те «32 000 файлов * 128 МБ» помещается в ОЗУ NameNode; те же 4 ТБ как «150 миллионов * 30 КБ» могут съесть гигабайты памяти метаданных, повысить время GC и нагрузку на RPC-каналы.

  1. Hive.
    Когда в Hive (или Presto, Impala) выполняется запрос к таблице, система сначала разбивает данные на части, которые называются сплиты (splits) как и везде в МапРедюсе Хадупа.
    Каждый файл, даже самый маленький, становится отдельным сплитом, если его размер меньше размера блока HDFS.

Что это значит:

На каждый файл создаётся отдельная задача на чтение (map-task или поток-ридер).

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

Система начинает тратить ресурсы впустую: на каждую маленькую задачу надо открыть файл (open()), потом закрыть (close()), переключиться между дисками и узлами кластера (ухудшается locality — файлы могут оказаться далеко от машины, которая их обрабатывает).

Из-за этого процессоры часто просто ждут данные, не выполняя реальной работы (idle-время растёт), и нагрузка на файловую систему увеличивается.

Итог: вместо того чтобы эффективно обрабатывать большие объёмы данных, система заваливается в огромные накладные расходы на обслуживание миллионных количеств мелких файлов.

  1. Metastore-ад (и проблема «дрейфа партиций»).
    Hive Metastore — это база данных, где хранятся все метаданные о таблицах: какие у них партиции, какие файлы относятся к какой партиции, какие есть схемы и т.д.

Что происходит с мелкими файлами:

Если у вас в таблице заведено разбиение, например, по дате и часу (dt=2025-04-26, hr=13), то под каждую дату и час создаётся отдельная партиция.

В нормальной ситуации в одной партиции лежит несколько файлов (скажем, 5–10 крупных файлов).

При мелких файлах в одной партиции может оказаться десятки тысяч записей о файлах вместо нескольких штук.

Это приводит к тому, что любые операции на уровне метастора:

    SHOW PARTITIONS — показать список всех партиций,

    ANALYZE TABLE — пересчитать статистику для оптимизации запросов,

    MSCK REPAIR TABLE — восстановить связи между файлами и метастором,

начинают занимать часы или даже дни.
Потому что метастору приходится обрабатывать гигантские списки файлов вместо нормального компактного списка.

Итог: производительность всей системы проседает, а обслуживание таблиц становится проблемой само по себе.

Две «стороны» решения
А) Лечим последствия — периодически собираем мелочь в крупные файлы (compaction).
Б) Лечим причину — заставляем прод-сервисы отдавать данные батчами/буферами, чтобы файлы изначально были «толстыми».

Практический рецепт ручной компакции (Spark-way)

  1. Выбираем срез (обычно одна партиция dt=2025-04-24/hr=13 или «всё, что старше N дней»).
  2. Читаем
    python
    df = spark.read.parquet(src_path)
  3. Схлопываем до небольшого числа партиций:
    python
    df = df.repartition(1)          # или .coalesce(4) под ваш HDFS blocksize
  4. Пишем во временную директорию dst_path_tmp в том же формате + compression (Snappy/ZSTD).
  5. Проверяем (count(), md5sum, выборка 100 строк).
  6. Атомарный swap: hdfs dfs -mv dst_path_tmp src_path_new && hdfs dfs -rm -r src_path_old.
  7. Удаляем лишнее: hdfs dfs -expunge, запускаем hdfs fsck для валидации.
  8. Когда запускать? При «охлаждении» данных: часовые партиции → дневные, дневные → месячные. Время простоя ETL важно меньше, чем продуктивные SLA.

Тонкие места и corner-cases

|———-|———–|

Отдельно: автоматизация на ваших инструментах (Spark + Hadoop + Kafka + Airflow)

1. Kafka → HDFS: не производить мелочь
Kafka Connect HDFS Sink
flush.size После скольких сообщений накопления отправлять данные в файл. Чем больше значение — тем больше файл на выходе.
rotate.interval.ms Максимальное время ожидания накопления данных перед тем как записать файл, даже если flush.size ещё не достигнут.
hdfs.block.size Размер HDFS-блока для файлов. Лучше ставить близко к реальному размеру файлов — например, 128 МБ или 256 МБ.
Spark Structured Streaming
trigger(availableNow=True) Говорит Spark-у: «Накопи как можно больше данных и запиши их одним большим куском».
maxRecordsPerFile Ограничение: сколько строк/сообщений писать в один файл. Если ставишь побольше — файлы получаются крупнее.
2. Spark-компактор как repeatable job в спрак стримминг

```python
def compact(partition_path:str):
(spark.read.parquet(partition_path)
.repartition(1)
.write.mode(‘overwrite’)
.parquet(partition_path + ‘_tmp’))
hadoop.mv(partition_path + ‘_tmp’, partition_path)
~~~

  • Конфиги: spark.sql.files.maxPartitionBytes=128m, spark.executor.memoryOverhead, spark.sql.shuffle.partitions — чтобы job не раскатывал 200 шардиций.
  • Логику свопа держите в единичной shell-функции с hdfs dfs -mv, чтобы операция была атомарной для читателей.

3. Airflow DAG, который сам решает «нужна ли компакция»

```python
from airflow.providers.apache.spark.operators.spark_submit import SparkSubmitOperator
from airflow.sensors.base import BaseSensorOperator

class SmallFilesSensor(BaseSensorOperator):
def poke(self, context):
cnt = hdfs_count_files(‘/data/dt=2025-04-24’)
return cnt > 10_000 # ваш порог

with DAG(‘hdfs_compaction’, schedule_interval=’0 3 * * *’) as dag:
wait_small = SmallFilesSensor(task_id=’check’)
compact = SparkSubmitOperator(
task_id=’run_compact’,
application=’s3://scripts/compact.py’,
conf={‘spark.driver.memory’:’4g’},
application_args=[’–partition’, ‘{{ ds }}’]
)
wait_small&raquo_space; compact
~~~

Sensor проверяет, что файлов в партиции больше порога или средний размер < 32 МБ; тогда триггерится Spark-job.

4. Мониторинг и алерты

  • HDFS FSCK в Airflow → Prometheus: метрики Total blocks (validated) и Avg block size.
  • NameNode JMX: NumFiles, BlocksTotal, FilesTotal — если начинают расти экспоненциально — триггерим DAG раньше расписания.
  • Kafka Connector metrics (records-per-batch, rotate-latency-avg) — поймёте, что коннектор пополз писать мелочь.

5. Правило двух попыток

  1. Сперва боретесь на входе (Kafka/Streaming ставит крупные батчи).
  2. Остаточную мелочь убирает ночной Airflow-компактор.

Так вы не забросите NameNode миллиардами блоков и получите процесс, который живёт сам, не требуя ежемесячного «ручного» Spark-сессана.

| Реестр схем Avro/Parquet менялся| Пишите компакцию через mergeSchema, иначе Spark уронит job. |

| Таблица под Hive ACID | Делайте insert overwrite, чтобы не сломать write-IDs. |

| В файлах есть курьёзные permisssion/ACL | Клонируйте hdfs dfs -cp -p, чтобы сохранить атрибуты. |

| В кластере смешанные blocksize 128/256/512 МБ | Выравнивайте параметр dfs.blocksize или пишите compaction по разным селекторам. |

Ситуация | Что учесть |

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Как выглядит партиция в Хадупе? #Ярослав

A

Вложенные друг в друга директории.

Например, таблица orders в бд shop с партициями по году и месяцу может выглядеть так:
/shop.db/orders/year=2024/month=06/part-00000-33b48309-0442-4e86-870f-f3070268107f-c000.snappy.parquet
/shop.db/orders/year=2024/month=06/part-00001-33b48309-0442-4e86-870f-f3070268107f-c000.snappy.parquet
/shop.db/orders/year=2024/month=06/part-00002-33b48309-0442-4e86-870f-f3070268107f-c000.snappy.parquet
/shop.db/orders/year=2024/month=07/part-00000-5daj5809-1551-8h46-83jn-dsdad8sdads6-d1d0.snappy.parquet
/shop.db/orders/year=2024/month=07/part-00001-5daj5809-1551-8h46-83jn-dsdad8sdads6-d1d0.snappy.parquet

При этом колонки year и month будут исключены из паркетов, т.к. их значения уже хранятся в названиях директорий. При обращении к таблице обычно они подтягиваются движком и отображаются.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Чем Hadoop отличается от PgSQL #Астон

A

o Hadoop – распределенная система для хранения и обработки больших объемов данных (batch-ориентирована), а PostgreSQL – реляционная СУБД с сильной транзакционной семантикой.
o Hadoop масштабируется горизонтально (добавлением узлов), PostgreSQL чаще масштабируют вертикально (увеличивая ресурсы одного сервера) или используют шардирование.
o Hadoop фокусируется на аналитической обработке, PostgreSQL – на OLTP (оперативных транзакциях) и аналитике меньших объемов.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Какой размер блоков в Hadoop? #Ярослав

A

По умолчанию в современных версиях Hadoop размер блока 128 МБ (ранее было 64 МБ), но этот параметр можно конфигурировать.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Как в хадупе получить Merge Join? #wildberries

A
  • Понятие Merge Join: В классических СУБД (Postgres, Oracle) Merge Join выполняется над отсортированными наборами. В Hadoop (в частности, в Hive) схожий механизм достигается благодаря bucketing и sorting а в конечно итоге уникальному джойну Хадупа SORT MERGE BUCKET.
  • Bucketing (бакетинг) в Hive**:
    1. Используем DDL типа:
    CREATE TABLE mytable (

    )
    CLUSTERED BY (join_key)
    SORTED BY (join_key)
    INTO N BUCKETS;
  1. При таком определении таблица делится на «бакеты» (файлы), причём каждая строчка попадает в бакет по хешу join_key.
  2. Если мы одинаково настроим bucketing (и sorting) для двух таблиц по одним и тем же ключам и с одинаковым числом бакетов, то при JOIN по join_key Hive понимает, что данные внутри каждого бакета уже отсортированы и «соотносятся» (co-located).
    * Эффект:
    o Hive (или Spark SQL) может выполнить более эффективный Merge Join, так как внутри каждого бакета данные уже отсортированы, и можно «сливать» (merge) без дополнительной сортировки или shuffle.
    o Условие, чтобы число бакетов и ключи бакетинга в обеих таблицах совпадали или число бакетов было кратно друг другу. Тогда join внутри каждого бакета идёт локально, упрощая перераспределение.

Принцип работы SMB Join Есть левая и правая таблица. В левой ( clients ) имеются два бакета, а в правой (sa les ) - четыре. Для работы SMB Join нужно соответствие в количестве бакетов между двумя таблицами. Берется хэш от значения поля, делится на количество бакетов и остаток от них будет соответствовать бакету, в которым лежат данные. Бакет 0 в таблице clients - означает, что остаток от деления хэша id из таблицы clients , деленный на 2 (количество бакетов) будет равняться 0. Этому бакету будут соответствовать бакет 0 и бакет 2 из таблицы sales . Таким образом все эти данные могут попасть на один mapper и в рамках него заджойниться. Стадии reduce и стадии shuffle в данном случае не будет. Следует иметь в виду, что при insert в таблицу, которая ранее была поделена на бакеты, может произойти такое, что часть данных, которая была загружена этой операцией, не будет поделена бакеты и таким образом SMB Join отработает некорректно.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Без чего не может работать Hadoop? #Rubbles

A
  • На базовом уровне Hadoop (HDFS) не может работать без NameNode, так как именно NameNode управляет метаданными всей файловой системы.
    o Если NameNode упал (и нет кластерного HA-решения), данные становятся недоступны, хотя физически блоки на DataNodes существуют.
  • Если смотреть шире, можно сказать, что без YARN (или другого resource manager) полный стект (Hadoop 2.x/3.x) не сможет распределять задания (MapReduce, Spark и т.д.) по кластерам.
    o Но чисто HDFS (без исполнения вычислительных задач) может жить без YARN.
  • Часто говорят, что NameNode — это «точка единого отказа» (Single Point of Failure). В современных продакшен-кластерах обычно используют HA NameNode (двойной NameNode + журнал JN), чтобы избежать SPOF.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Сколько займёт файл 10мб в хадупе? #Ярослав

A

30 МБ суммарно на трёх дата нодах + 420 байт в NameNode

Хадуп хранит данные по блокам, обычно 128МБ. Однако это не значит, что будет зарезервировано всё место блока, поэтому будет создана информация об одном блоке и одном файле размером 10 МБ. Если бы файл был больше размера блока, тогда занял бы кратное количество блоков с округлением вверх (300 МБ = 3 блока и тд).

С другой стороны, есть репликация (стандартный фактор репликации = 3). Это значит, что если мы помещаем один файл, он будет храниться в трёх местах (две копии). Такая избыточность в хранении позволяет использовать “дешёвое” железо, которое будет периодически умирать, а копии файлов будут восстанавливаться из других реплик.
Обычно не больше одной реплики блока на диск и не больше двух реплик на серверную стойку (группу нод). Поэтому 10 МБ х 3 = 30 МБ.

Бонус: на NameNode хранятся метаданные о том, как называется файл, где лежат реплики, на какие блоки разбит (если размер больше 1 блока).
. Метаданные об имени, дате создания и других атрибутах: 150 байт
. Маппинг блоков, связь между файлом и блоками: 150 байт (т.к. 1 файл = 1 блок)
. Инфа о репликах, на какой ноде лежит очередная копия блока: 40 байт х 3 = 120 байт

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Что такое map reduce? #тг

A

MapReduce – это модель параллельных вычислений, представленная компанией Google, которая используется для работы с большими объёмами данных в Hadoop кластере.

Модель вычислений MapReduce состоит из стадий:
1. Map: выполняемая параллельно фаза отображения, в которой входные данные разделяются на конечное множество блоков для последующей обработки. Как правило, вычисления легковесны, выполняются параллельно и независимо. Например, нам нужно по какому-то условию отфильтровать данные.
2. Shuffle: операция передачи данных от Map к Reduce (перемешивание и рассылка).
3. Reduce: фаза свёртки, в которой вывод фазы отображения агрегируется для получения конечного результата. На каждый Reducer попадут значения с одним ключом (будут сгруппированы). Например, операции группировки, сортировки, нахождения агрегированных значений.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Что такое HDFS блоки и какие у них есть минусы?

A

Блок в HDFS (Hadoop Distributed File System) — это единица хранения файла, раздел файла, который распределяется по кластерам (нодам) в системе Hadoop.
Но важно: в отличие от классических файловых систем, таких как ext4 или NTFS, в HDFS:

Блоки логические, а не физические.
Это не прямое отображение на физические сектора диска.

Файл разбивается на блоки только логически; разные блоки одного файла могут быть на разных машинах. Соответственно, исходный файл разделяется на блоки по 128 МБ, которых может быть десять, а несколько тысяч. Каждый блок с информацией реплицируется на несколько узлов для обеспечения отказоустойчивости.

Минусы HDFS блоков:

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

Преимущества блоков HDFS
1. Файл может быть больше любого отдельного диска в сети:
o Блоки файла совершенно необязательно хранить на одном диске; они могут использовать любые диски в кластере.
o Более того, при хранении файла в кластере HDFS его блоки могут быть распределены по всем дискам кластера (хотя эта ситуация несколько нетипична).
2. Упрощение подсистемы хранения:
o Использование в качестве абстрактной единицы блока вместо файла упрощает подсистему хранения.
o Простота — желанное свойство любых систем, но она особенно важна в распределенных системах с их разнообразными возможными режимами отказов.
o Использование блоков в подсистеме хранения данных упрощает хранение (так как блоки имеют фиксированный размер, система может легко вычислить количество блоков, которые могут храниться на заданном диске) и устраняет проблемы с метаданными (блок — всего лишь фрагмент данных, предназначенный для сохранения, с ним не нужно сохранять метаданные файла — скажем, информацию о разрешениях доступа, которые могут отдельно обрабатываться другой системой).
3. Улучшение отказоустойчивости и доступности системы:
o Блоки хорошо вписываются в механизм репликации.
o Для защиты от поврежденных блоков и сбоев дисков/машин каждый блок реплицируется на небольшом количестве физически разделенных машин (как правило, трёх).
o Если блок становится недоступным, его копия читается из другого места, причём это происходит прозрачно для клиента.
o Блок, ставший недоступным из-за повреждения данных или сбоя оборудования, копируется из альтернативных хранилищ на другие работоспособные машины, чтобы довести фактор репликации до нормального уровня.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Почему мелкие файлы вреды с точки зрения диска и i o

A

Основные понятия:

Отличный вопрос.
Давай объясню абсолютно точно, что именно это значит:
что такое sequential операция, что такое seek, и почему это критично для Hadoop HDFS и вообще для большого IO.

Допустим: у тебя есть большой файл 128 МБ, лежащий на HDFS.
Как его можно прочитать?

Термин | Что это значит |
|:—|:—|
| Sequential IO | Последовательное чтение большого куска данных без прерываний. Физический диск (или сеть) просто читает байты подряд. |
| Seek | Операция “прыжка” по позиции в файле: нужно перепозиционировать головку чтения или сделать новую сетевую операцию, чтобы получить данные из другого места. |
| IO-операция | Любая операция ввода-вывода: чтение с диска, чтение по сети, запись на диск и т.д. |

  • Открывается один поток чтения (InputStream).
  • Одна операция открытия файла.
  • Идёт одна непрерывная последовательная операция чтения (sequential read) 128 МБ подряд, блок за блоком.

Что происходит на железе:
- Если это диск — головка движется ровно по дорожке без остановок.
- Если это сеть — TCP-сессия тянет подряд данные.
- Минимум затрат на перемещения и установку соединений.
- Очень быстро.

Время = минимально.
Пропускная способность = максимальная.

Тогда:
- Нужно открыть 128 разных файлов.
- На каждый файл:
- Открыть соединение,
- Найти в HDFS где он лежит,
- Спросить NameNode,
- Открыть DataNode поток,
- Сделать seek до начала файла (если нужно),
- Прочитать 1 МБ,
- Закрыть поток.

Что происходит на железе:
- При каждом открытии файла:
- Диск делает seek — механический прыжок головки.
- Сеть делает установку TCP-сессии.
- Протоколы типа HDFS делают handshake и setup потока.

Итог:
- Ты потратил кучу времени на открытие файлов (open/close).
- Ты сделал сотни/thousands физических seek-ов вместо одного.
- Много лишних метаданных у NameNode.
- Скорость падает в разы.

| Причина | Последствия |
|:—|:—|
| Физика диска | На HDD seek = механическое движение головки на новое место. Это может занимать миллисекунды, а чтение без seek’ов идёт со скоростью в сотни мегабайт в секунду. |
| HDFS | Каждый seek = лишний RPC-запрос к NameNode + настройка DataNode-сессии. |
| Сеть | Много открытых TCP-соединений, установка TCP handshake → огромная нагрузка на сетевую стек. |

И самое страшное:
- Seek-операции не параллелятся эффективно.
- И их стоимость не уменьшается, даже если у тебя очень быстрые диски или сети.

| Сценарий | Затраты на 128 МБ |
|:—|:—|
| Sequential read одного большого файла | Около 1 секунды (сеть+диск) |
| 128 отдельных seek и чтений по 1 МБ | До 30–60 секунд (накладные расходы × 128 операций) |

> “Блок 128 МБ читается в одну sequential-операцию, а 128 МБ, разбитые на 128 × 1 МБ, вызывают тысячи seek-ов”

переводится на человеческий язык как:

> Если у тебя куча мелких файлов, то чтобы прочитать данные, система будет постоянно прыгать по диску и по сети,
вместо того чтобы быстро и плавно прогнать данные в один поток.
Это убивает производительность в разы.

  • Стремятся к файлам размера ≈ 128–256 МБ минимум.
  • Если файлов мелких много — делают слияние файлов (merge small files).
  • Или используют архивы (HAR), объединённые input-форматы (CombineFileInputFormat).
  • Или меняют архитектуру партиционирования и бакетирования.

| Правильный способ | Плохой способ |
|:—|:—|
| Большие файлы (> 128 МБ) → быстро, мало операций | Много мелких файлов (<1 МБ) → тормоза, миллион seek-ов |

Хочешь, я ещё приведу конкретный реальный кейс из продакшн Hive + Tez проекта, где маленькие файлы убили job с миллионом tasks, и как мы решили это через bucketing+merge? Очень наглядная история будет.
Показать? 🚀

How well did you know this?
1
Not at all
2
3
4
5
Perfectly