Вы находитесь на странице: 1из 44

Cловарь (справочная информация)

● Реляционная база данных – это набор данных с предопределенными связями


между ними.
● Реляционная система управления базами данных (RDBMS/РСУБД) - это
программная система, обеспечивающая доступ к реляционной базе данных.
● OLTP (англ. Online Transaction Processing), транзакционная система —
обработка транзакций в реальном времени.
● OLAP (англ. online analytical processing, интерактивная аналитическая
обработка) — технология обработки данных, заключающаяся в подготовке
суммарной (агрегированной) информации на основе больших массивов данных,
структурированных по многомерному принципу.
● ACID (от англ. atomicity, consistency, isolation, durability) — набор требований к
транзакционной системе, обеспечивающий наиболее надёжную и
предсказуемую её работу — атомарность[⇨], согласованность[⇨], изоляция[⇨],
устойчивость[⇨].
● HDFS (Hadoop Distributed File System) — распределенная файловая система
Hadoop для хранения файлов больших размеров с возможностью потокового
доступа к информации, поблочно распределённой по узлам вычислительного
кластера, который может состоять из произвольного аппаратного обеспечения.
● Hive — система управления базами данных на основе платформы Hadoop с
SQL-подобным языком запросов, позволяет выполнять запросы, агрегировать и
анализировать данные; компонент экосистемы Hadoop.
● Hive Query Language (HiveQL) - это язык запросов в Apache Hive для
обработки и анализа структурированных данных. Он отделяет пользователей от
сложности программирования Map Reduce. В нем повторно используются
общие понятия из реляционных баз данных, такие как таблицы, строки, столбцы
и схемы, что облегчает обучение.
● Вертикальное масштабирование — увеличение производительности каждого
компонента системы с целью повышения общей производительности.
● Горизонтальное масштабирование — разбиение системы на более мелкие
структурные компоненты и разнесение их по отдельным физическим машинам
(или их группам), и (или) увеличение количества серверов, параллельно
выполняющих одну и ту же функцию.
● Apache Hadoop YARN — это система для планирования заданий и управления
кластером.
● Стирающий код[1] (англ. Erasure code) — в теории кодирования
помехоустойчивый код[1], способный восстановить целые пакеты данных в
случае их потери[2].

1) Что такое Hadoop? Назовите его основные компоненты и для


чего они нужны?
Что такое Hadoop?
Hadoop – это свободно распространяемый набор утилит, библиотек и фреймворк для
разработки и выполнения распределённых программ, работающих на кластерах из
сотен и тысяч узлов. Эта основополагающая технология хранения и обработки
больших данных (Big Data) является проектом верхнего уровня фонда Apache Software
Foundation.

Основные компоненты Hadoop и их роли


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

Проект состоит из основных 4-х модулей:

1. Hadoop Common – набор инфраструктурных программных библиотек и


утилит, которые используются в других решениях и родственных проектах, в
частности, для управления распределенными файлами и создания
необходимой инфраструктуры;
2. HDFS – распределённая файловая система, Hadoop Distributed File System –
технология хранения файлов на различных серверах данных (узлах,
DataNodes), адреса которых находятся на специальном сервере имен
(мастере, NameNode). За счет дублирования (репликации) информационных
блоков, HDFS обеспечивает надежное хранение файлов больших размеров,
поблочно распределённых между узлами вычислительного кластера;
3. YARN – система планирования заданий и управления кластером (Yet Another
Resource Negotiator), которую также называют MapReduce 2.0 (MRv2) –
набор системных программ (демонов), обеспечивающих совместное
использование, масштабирование и надежность работы распределенных
приложений. Фактически, YARN является интерфейсом между аппаратными
ресурсами кластера и приложениями, использующих его мощности для
вычислений и обработки данных;
4. Hadoop MapReduce – платформа программирования и выполнения
распределённых MapReduce-вычислений, с использованием большого
количества компьютеров (узлов, nodes), образующих кластер

Ещё есть Spark

Apache Spark (от англ. spark — искра, вспышка) — фреймворк с открытым исходным
кодом для реализации распределённой обработки неструктурированных и
слабоструктурированных данных, входящий в экосистему проектов Hadoop. В отличие от
классического обработчика из ядра Hadoop, реализующего двухуровневую концепцию
MapReduce с хранением промежуточных данных на накопителях, Spark работает в
парадигме резидентных вычислений (англ. in-memory computing) — обрабатывает данные
в оперативной памяти, благодаря чему позволяет получать значительный выигрыш в
скорости работы для некоторых классов задач[7], в частности, возможность многократного
доступа к загруженным в память пользовательским данным делает библиотеку
привлекательной для алгоритмов машинного обучения[8].
История появления и развития Hadoop
2002
Дуг Каттинг и Майк Кафарелла работают над проектом Apache Nutch, целью которого
является создание веб-поисковой системы, способной просматривать и индексировать
веб-сайты.
После долгих исследований Майк Кафарелла и Даг Каттинг подсчитали, что для
системы, поддерживающей индекс в один миллиард страниц, потребуется около
$500000 на оборудование с ежемесячными текущими расходами в $30 000.
Этот проект оказался слишком дорогим и поэтому был признан невыполнимым для
индексирования миллиардов веб-страниц. Поэтому они искали приемлемое решение,
которое позволило бы снизить стоимость.

2003
Компания Google выпускает статью о распределенной файловой системе Google
(GFS), в котором описывалась архитектура GFS, представляющая идею хранения
больших массивов данных в распределенной среде. Эта статья решала проблему
хранения больших файлов, создаваемых в процессе индексации и сканирования
веб-страниц. Но это лишь половина решения проблемы.

2004
Разработчики Nutch приступили к написанию открытой реализации Nutch Distributed
File System (NDFS).
Компания Google выпускает статью о MapReduce. В статье было решение для
обработки больших массивов данных.
Разработчики Nutch внедрили MapReduce в середине 2004 года.

2006
Сообщество Apache осознало, что реализация MapReduce и NDFS может быть
использована и для других задач. В феврале 2006 года они вышли из Nutch и
сформировали независимый подпроект Lucene под названием "Hadoop".

2011 – 2012
27 декабря 2011 года Apache выпустил Hadoop версии 1.0, включающей поддержку
Security, Hbase и др.
23 мая 2012 года была выпущена версия Hadoop 2.0.0-alpha. Этот релиз содержит
YARN.

2017 – …
13 декабря 2017 года был доступен релиз 3.0.0

Отличия между версиями 1, 2, 3 Hadoop

Hadoop 1 vs Hadoop 2

1. Компоненты: В Hadoop 1 у нас есть MapReduce, но в Hadoop 2 есть YARN (Yet


Another Resource Negotiator) и MapReduce версии 2.

2. Демоны:
Hadoop 1 Hadoop 2

Namenode Namenode

Datanode Datanode

Secondary Namenode Secondary Namenode

Job Tracker Resource Manager

Task Tracker Node Manager

3. Работа:
В Hadoop 1 есть HDFS, которая используется для хранения данных, и Map Reduce,
который работает как управление ресурсами, так и обработка данных. Из-за такой
нагрузки на Map Reduce, это влияет на производительность.

В Hadoop 2 снова есть HDFS, которая используется для хранения данных, а поверх
HDFS есть YARN, который работает как управление ресурсами. Он в основном
распределяет ресурсы и поддерживает все процессы.

4. Ограничения:
Hadoop 1 представляет собой архитектуру Master-Slave. Она состоит из одного
ведущего узла и нескольких ведомых. Предположим, если ведущий узел вышел из
строя, то независимо от того, насколько хороши ваши ведомые узлы, ваш кластер
будет разрушен. Опять же, для создания такого кластера необходимо копировать
системные файлы, файлы образов и т.д. на другую систему, что занимает слишком
много времени и не может быть приемлемо для организаций в наше время.

Hadoop 2 также представляет собой архитектуру Master-Slave. Но она состоит из


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

Hadoop 2 vs Hadoop 3

Hadoop 2 Hadoop 3

Отказоустойчивость Репликация - это Для обеспечения


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

Балансировка Балансировщик HDFS Используется


используется для балансировщик внутри
балансировки данных датанод, который
вызывается через
интерфейс командной
строки HDFS disk-balancer.
Схема хранилища Используется схема использует стирающее
репликации 3x кодирование в HDFS

Оверхед хранилища В Hadoop 2.x потребляется 50% HDFS


200% HDFS

Масштабируемость Ограниченная Улучшена


масштабируемость, в масштабируемость, в
кластере может быть до кластере может быть
10000 узлов более 10000 узлов

Восстановление Для восстановления Не требуется ручного


Namenode namenode требуется вмешательства для
ручное вмешательство восстановления namenode

Источники информации:
https://www.bigdataschool.ru/wiki/hadoop
https://data-flair.training/blogs/hadoop-history/
https://www.geeksforgeeks.org/difference-between-hadoop-1-and-hadoop-2/
https://www.geeksforgeeks.org/difference-between-hadoop-2-x-vs-hadoop-3-x/?ref=rp

Комментарии лектора: HDFS + Hive + Spark (но он как дополнение, не как основа) +
Yarn
Основные стадии развития: MapReduce у Гугла, хадуп версия 1, 2, 3 (лектор говорит,
что изменений не много)

2) В чем отличие между Hadoop и классической реляционной


базой данных?

Сравнение характеристик Hadoop и RDBMS кратко в таблице

Hadoop RDBMS

Формат хранимых Структурированные, Только структурированные


данных полуструктурированные и данные
неструктурированные
данные

Масштаб данных Большие наборы данных Средние размеры данных


(Терабайты и петабайты) (Гигабайты)

Формат запросов Hive Query Language SQL


(HQL)

Схема Схема данных требуется Схема данных требуется


во время чтения во время записи
(динамическая схема) (статическая схема)

Скорость операций Записи и чтения быстрые Чтения быстрые

Доступность В открытом доступе Может иметься платная


лицензия
Область применения OLAP OLTP

Объекты данных Работает с парами Работает с реляционными


ключ-значение таблицами

Пропускная способность Высокая Низкая

Масштабируемость Горизонтальная² Вертикальная

Аппаратные средства Стандартное Высокопроизводительные


оборудование (commodity) серверы

Целостность информации ACID поддерживается не Высокая (поддерживается


всеми компонентами ACID)
Hadoop¹

¹ Изначально HDFS не поддерживает изменения в существующих файлах и не


обеспечивает согласованность чтения, если операция записи добавляет
данные в файл, уже читаемый другим пользователем. До Hive версии 0.13
атомарность, согласованность и долговечность поддерживались на уровне
раздела, а изоляция использовалась для механизма блокировки отдельных
операций, но отсутствовала для транзакций в целом. С версии 0.13, все
функции ACID стали полностью поддерживаться.

² Одной из основных целей Hadoop изначально было обеспечение


горизонтальной масштабируемости кластера посредством добавления
недорогих узлов, без прибегания к мощным серверам и дорогим сетям
хранения данных. Тем не менее, считается, что горизонтальная
масштабируемость в Hadoop-системах ограничена, для Hadoop до версии 2.0
максимально возможно оценивалась в 4 тыс. узлов при использовании 10
MapReduce-заданий на узел. Во многом этому ограничению способствовала
концентрация в модуле MapReduce функций по контролю за жизненным циклом
заданий, считается, что с выносом её в модуль YARN в Hadoop 2.0 и
децентрализацией — распределением части функций по мониторингу на узлы
обработки — горизонтальная масштабируемость повысилась.
Плюсы и минусы Hadoop

Плюсы

Открытый исходный код, экономически эффективное аппаратное обеспечение


Hadoop имеет открытый исходный код и использует экономически эффективное
аппаратное обеспечение, что обеспечивает экономически эффективную модель, в
отличие от традиционных реляционных баз данных, которые требуют дорогостоящего
оборудования и высокопроизводительных процессоров для работы с Большими
данными. Проблема традиционных реляционных баз данных заключается в том, что
хранение большого объема данных нерентабельно, поэтому компании начали удалять
необработанные данные, что может привести к неправильному сценарию развития их
бизнеса. Средство Hadoop предоставляет нам 2 основных преимущества, одно из
которых заключается в том, что оно с открытым исходным кодом, а значит свободно в
использовании, а второе - в том, что оно использует аппаратное обеспечение, которое
также является недорогим.
Масштабируемость
Hadoop - это высокомасштабируемая модель. Большой объем данных делится на
несколько недорогих машин в кластере, которые обрабатываются параллельно.
Количество этих машин или узлов может быть увеличено или уменьшено в
соответствии с требованиями предприятия. В традиционных RDBMS системы не могут
быть масштабированы для работы с большими объемами данных.
Гибкость
Hadoop разработан таким образом, что он может эффективно работать с
любыми типами данных, такими как структурированные (MySql Data),
полуструктурированные (XML, JSON), неструктурированные (изображения и видео).
Это означает, что он может легко обрабатывать любые данные независимо от их
структуры, что делает его очень гибким.
В то время как обычные RDBMS могут работать лишь со структурированными
данными.
Скорость
Hadoop использует распределенную файловую систему для управления хранением
данных, т.е. HDFS (Hadoop Distributed File System). В DFS (распределенной файловой
системе) файл большого размера разбивается на блоки небольшого размера, затем
распределяется между узлами, имеющимися в кластере Hadoop, поскольку это
огромное количество блоков файла обрабатывается параллельно, что делает Hadoop
быстрее, благодаря чему он обеспечивает высокую производительность по сравнению
с традиционными системами управления базами данных. Когда вы имеете дело с
большим количеством неструктурированных данных, скорость является важным
фактором, с Hadoop вы можете легко получить доступ к ТБ данных всего за несколько
минут. Этим не может похвастаться RDBMS.
Отказоустойчивость
В Hadoop данные реплицируются на различные DataNodes в кластере Hadoop, что
обеспечивает доступность данных, если какая-либо из ваших систем выйдет из строя.
Вы можете прочитать все данные с одной машины, если на этой машине возникнут
технические проблемы, данные также могут быть прочитаны с других узлов в кластере
Hadoop.
Высокая пропускная способность
Hadoop работает на основе распределенной файловой системы, где различные
задания назначаются на различные узлы данных в кластере, батч этих данных
обрабатывается параллельно в кластере Hadoop, что обеспечивает высокую
пропускную способность. Пропускная способность - это не что иное, как задача или
работа, выполняемая в единицу времени.
Минимальный сетевой трафик
В Hadoop каждая задача делится на различные небольшие подзадачи, которые затем
назначаются каждому узлу данных, имеющемуся в кластере Hadoop. Каждый узел
данных обрабатывает небольшой объем данных, что приводит к низкому трафику в
кластере Hadoop.
Минусы

Проблемы с маленькими файлами


Hadoop может эффективно работать с небольшим количеством файлов большого
размера. Hadoop хранит файлы в виде файловых блоков размером от 128 МБ (по
умолчанию) до 256 МБ. Hadoop испытывает проблемы, когда ему нужно получать
доступ к файлам небольшого размера часто. Такое большое количество маленьких
файлов перегружает Namenode и затрудняет его работу.
Уязвимость
Hadoop - это структура, написанная на языке java, а java является одним из наиболее
часто используемых языков программирования, что делает его более небезопасным,
поскольку им может легко воспользоваться любой киберпреступник.
Низкая производительность в окружении малых данных
Hadoop в основном предназначен для работы с большими массивами данных, поэтому
его можно эффективно использовать для организаций, генерирующих большой объем
данных. Его эффективность снижается при работе с небольшим объемом данных.
Отсутствие безопасности
Hadoop использует Kerberos для обеспечения безопасности, которым нелегко
управлять. В Kerberos отсутствует шифрование хранилищ и сетей.
Высокоуровневая обработка
В Hadoop чтение и запись данных производится с диска, что затрудняет выполнение
вычислений в памяти и приводит к накладным расходам на обработку.
Поддерживает только обработку батчами
Пакетный процесс — это процессы, которые выполняются в фоновом режиме и не
имеют никакого взаимодействия с пользователем. Движки, используемые для этих
процессов внутри ядра Hadoop, не слишком эффективны. С их помощью невозможно
получить результат с низкой задержкой.
Плюсы и минусы RDBMS

Плюсы
Простота использования
Это одно из самых больших преимуществ реляционной базы данных; РСУБД имеет
удобный для пользователя формат таблиц, данные в которых организованы в
соответствии с естественной структурой. Это также облегчает доступ к данным и
манипулирование ими, а также позволяет легко находить совпадающие записи.
Сетевой доступ
Программа в РСУБД разработана специально для перехвата запросов, передаваемых
по сети, облегчая взаимодействие клиента с базой данных. Пользователям не нужно
входить в систему для доступа к базе данных или ее использования, что обеспечивает
им большее удобство.
Язык
РСУБД поддерживает SQL, стандартный и знакомый язык; он имеет простой синтаксис
и использует английские фразы и ключевые слова, что делает его легким для изучения
и понимания. RDBMS также имеет возможность вставлять ключевые слова,
возможности и функции, не связанные с базой данных SQL.
Производительность
RDBMS по своей сути не является быстродействующей базой данных, но при
проектировании базы данных в нее встроено несколько оптимизаций, которые
фактически повышают производительность. В конечном итоге это приводит к высокой
производительности всех наборов данных и приложений.
Обслуживание
Обслуживать RDBMS проще, так как команда технической поддержки или
администраторы баз данных могут контролировать, тестировать, обслуживать и
выполнять резервное копирование баз данных, которые они имеют в своей основной
системе. Эти функции автоматизированы с помощью встроенных средств
автоматизации в операционной системе РСУБД.
Привилегии и безопасность данных
Доступ к базе данных контролируется и подлежит аутентификации администратором
базы данных, который имеет право предоставлять или отклонять доступ
пользователей. Это повышает безопасность базы данных.

Минусы
Стоимость
Создание и поддержка базы данных - довольно дорогое удовольствие, и,
следовательно, это один из самых больших недостатков РСУБД.
Специальное программное обеспечение, необходимое для создания и настройки
реляционной базы данных, стоит довольно дорого. Обновление всей информации для
обеспечения работоспособности программы также может оказаться сложной задачей,
особенно если ваша организация большая и имеет сложную базу данных.
В таких случаях может потребоваться помощь опытных программистов извне, чтобы
построить РСУБД на основе SQL. Вам также понадобится опытный администратор
РСУБД для управления и контроля над базой данных.
Недостаточная скорость
По сравнению с другими типами баз данных, RDBMS извлекает результаты довольно
медленно, и поэтому производительность значительно ниже.
Память
Поскольку СУБД хранит данные в таблицах, имеющих строки и столбцы, она занимает
большой объем физической памяти. Это означает дополнительные затраты на
увеличение объема памяти и является существенным недостатком.

Источники информации:
https://www.bigdataschool.ru/blog/acid-transactions-in-hive.html
https://www.geeksforgeeks.org/hadoop-pros-and-cons/
https://www.educba.com/hadoop-vs-rdbms/
https://webandcrafts.com/blog/advantages-disadvantages-rdbms/

Комментарии лектора: RDBMS, могут использоваться как OLTP и OLAP, рассказать


почему хадуп не оч для OLTP нагрузки (так как HDFS по факту распределенная
система на нескольких серверах, а это функционал, который не покрывается
реляционными базами данных), основные инструменты Хадупа плохо дружат с (raicid
??? не разобрал слово; думаю, что речь про ACID https://en.wikipedia.org/wiki/ACID).
Плюсы и минусы каждой системы, фактически где отличия

3) Как работает HDFS? Как хранятся файлы?

Комментарии лектора: Name node, разбиение на блоки, репликация, механизм


записи нового файла. Сказать про Secondary node, Data Node, {Мб что-нибудь про
HDFS Federation, High availability Name node слайд 9
(https://docs.google.com/presentation/d/1yF8pzHMS57Y9vCBMB-bEAkRoqA5YYaaSiKeBgJ
5iwAM/edit#slide=id.g47647813de_0_30)}

General HDFS design

Namenode – по сути дерево файловой системы и позволяет делать с собой примерно


тот же набор операций что и обычная posix-совместимая файловая система, следит за
разбиением файлов на блоки и их репликацией
Кластер DataNode – горизонтально масштабируемое блочное устройство хранения,
по сути жёсткий диск бесконечных размеров. Неймнода использует его для хранения
самих блоков данных

Namenode не шардируется и не реплицируется, что автоматически делает её


боттлнеком всей системы, а также ограничивает количество пишущих в один файл
единицей

Кластер DataNodes гипотетически может хранить в себе бесконечное количество


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

Также неймнода выполняет функцию детектора отказов для кластера DataNodes и


выполняет решардинг или ререпликацию в случае отказа одной из машин и/или
стоек

Репликация DataNode

Файлы в hdfs, как и в обычных файловых системах бьются на блоки, это позволяет
шардировать один большой файл, если он не помещается на 1 диск, а также сократить
время репликации, реплицируя только часть файла при изменении, а не весь.
При этом неймнода старается выбирать data nodы из разных стоек для репликации
блока, чтобы повысить отказоустойчивость. При этом когда необходимо прочитать
очередной блок, она выбирает для чтения ноду которая ближе всего к тому, кто
запрашивает данные.
Ребалансинг кластера

Также hdfs поддерживает схемы ребалансинга кластера и может добавлять новые


реплики для горячих шардов и перекидывать на добавленные ноды в датакластер
часть информации для равномерного распределения нагрузки
Secondary NameNode

По сути сервис снапшотов. Чтобы понять зачем он нужен стоит упомянуть как
работает namenode
Неймнода обеспечивает персистентность храня логи на диске + inmemory структуру
для быстрой обработки запросов, иногда надо делать лог компакшн и снапшот этой
инмемори структуры (иначе на следующем рестарте восстанавливать её из лога
длиной в несколько лет может занять продолжительное время).
Это требует дополнительных ресурсов которых и так не хватает. Соответственно
заведём вторичную неймноду которой будем транслировать наш лог, а она просто
будет делать из него снапшоты. Тогда при рестарте основной неймноды мы можем
просто стянуть у неё снапшот и докинуть не снапшотнутые изменения из своего лога,
что уменьшит даунтайм всего кластера.
При этом никогда не стоит использовать вторичную ноду для обработки
каких-либо запросов, так как это ломает линеаризуемость системы

https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsUserGuide.html
#Secondary_NameNode

High Availability Name Node

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

Так как для поддержания консистентности необходима имплементация Replicated State


Machine то персистентные логи теперь будем хранить на кластере Journal Nodes
которые будут Shared Memory для наших неймнод. Они гарантируют только одного
writer’a (Видимо через zookeeper, но я не уверен), и используют кворумные чтения и
записи, таким образом логи неймноды реплицируются и мы можем на горячую
подменить погибшую первичную неймноду вторичной

https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilit
yWithQJM.html
https://docs.cloudera.com/HDPDocuments/HDP2/HDP-2.1.2/bk_system-admin-guide/conten
t/ch_hadoop-ha-1.html

HDFS Federation

Идея: если мы так упираемся в NameNode, давайте шардируем её по


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

Какую проблему это решает:


Нам больше не надо разворачивать кластер data nodes под новый проект, мы можем
просто поднять новую неймноду с новым деревом файловой системы поверх уже
имеющегося “диска”

Какие проблемы это не решает:


Нет балансировки нагрузки,
Никакой отказоустойчивости это также не добавляет, если одна нода погибает, то
данные которые хранились в её поддереве недоступны пока мы её не поднимем.
Передать данные из одного поддерева в другое мы также не можем средствами hdfs
эту логику надо реализовывать на стороне клиента

4) Расскажите, что происходит когда в HDFS записывается


новый файл? Что происходит, когда выключается одна из
DataNode? Как NameNode понимает, что DataNode
выключилась?

Комментарии лектора: Цикл коммита файла на HDFS, когда у нас блоки, блоки
реплицированные. Когда выпадает одна из датанод, как хадуп понимает, что она
выпала (NameNode перестала получать от упавшей ноды хартбиты). Что происходит
когда неймнода восстанавливает реплику и как она ее восстанавливает.

Пост красивыми картинками описания HDFS


Деление на блоки. Разберемся сначала с тем как представляются файлы в HDFS.
Фактически файл бьется на блоки большого размера примерно 256мб (можно бить и
на блоки другого размера 64мб, 128мб и др.). Также последний блок бывает либо
меньше остальных, либо он очень маленький, то прикрепляется к предпоследнему
блоку.

Репликация блоков. Теперь перейдем к репликации. Будем делать 3 реплики (можно


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

Фактическая запись файла.


1. Сначала будем запрашивать у NameNode возможность сделать запись файла (у
клиента проверяют права доступа и то, что не возникнет конфликтов из-за
имени файла).
2. Далее клиенту отправляют список с адресами DataNode, на которые мы будем
реплицировать блоки нашего файла.
3. Отправляем каждый блок на свою DataNode, далее они реплицируют блоки по
стратегии, описанной выше (фактически NameNode сразу отправляет
метаинформацию на какие ноды будет репликация каждого блока).
4. Если произошла какая-то ошибка, то клиент отправляет жалобу на DataNode в
NameNode и запрашивает, куда нужно отправить не записавшиеся блоки
5. Ноды все записали, отправили ack клиенту, клиент подтвердил NameNode, что
запись сделана (тут могут быть трейдоффы в реализации, ждать ли ответ от
всех реплик, либо сразу отправлять ack после записи на главную реплику)
Про падение DataNode - часть статьи с названием Replication Management

Как NameNode понимает, что DataNode выключилась. При выключении DataNode она
перестает отправлять актуальную информацию о своем состоянии в NameNode.
Соответственно NameNode из-за отсутствия хартбитов понимает, что у нас пропали
какие-то реплики.

Что делает NameNode при отключении DataNode. Так как вся метадата хранится на
NameNode и мы можем легко понять с каких нод надо переместить информацию.
Далее информация о блоках добавляется в очередь с приоритетами (чтобы реплики,
которых осталось мало реплицировались в первую очередь), а после NameNode
отправляет команды нодам, что нужно отреплицировать такой-то блок данных на
такую-то другую ноду.

5) Почему не стоит хранить в HDFS много маленьких файлов?

Комментарии лектора: Сказать про то как файлы хранятся в HDFS, про метаданные
на NameNode, то что NameNode является узким местом. То что в 3 версии хадупа есть
HDFS Federation. Маленькие файлы создают неоправданно большую нагрузку + если
файл меньше блока, то занимает много неэффективного места.

Какая-то информация есть тут


https://www.bigdataschool.ru/blog/too-many-small-files-in-hdfs.html

Важно. Проблема маленьких файлов затрагивает только на NameNode и на


количество запросов в сети. DataNode при этом не будет проблемным местом, так как
разделение на блоки в Хадупе только логическое, физического места на диске
DataNode они будут занимать ровно столько же, сколько было данных в исходном
файле.

Теперь перейдем к проблемам. Для NameNode основная проблема будет в том, что
хранить мы будем очень много метадаты, так как архитектура Хадупа нацелена
именно на много данных из одного файла, а не на много данных из разных файлов.
Например, обычно одна структура для блока данных содержит 150 байт, значит, если
мы храним 1 файл на 16гб и блоки у нас по 256мб, то метаданных будет (16гб / 256мб)
* 150б = 9.6кб. А если мы храним те же 16гб, но в 1000 файлов по ~16мб, то
метаданных будет 1000 * 150б = 150кб (по одной структуре для каждого файла).
Фактически храним на NameNode в 15 раз больше метаданных при том, что
исходный общий размер файлов одинаковый. При расчетах стоит сказать еще про
репликацию, что метаданных на самом деле будет в обоих случаях больше в 3 раза,
так как храним еще и копии.

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

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

Доп информация, про нее вроде не рассказывали на лекциях. Для того, чтобы
бороться с маленькими файлами используют либо HAR, который как-то архивирует
данные, чтобы потом маппер отправил их в Хадуп как отдельный блок. В
системе Хадупа иерархия заархивированных файлов будет отображаться
также, как и без нее.

Доп информация. Другим способом борьбы с множеством маленьких файлов в


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

6) Что такое SecondaryNameNode? И что такое Checkpoint?

Комментарии лектора: Как SecondaryNameNode снимает слепки базы данных. Как


она потом делает запуск обычной нейм ноды, если нейм нода упала не сохранив свое
состояние, рассказ про работу неймноды

Важно. SecondaryNameNode не отвечает за выполнение каких либо команд в отличие


от NameNode. Это всего лишь фоновый процесс на отдельной машине, который
делает снимок всей системы (вероятно это называется Checkpoint).

Информация дальше взята из этого блога

Логи и NameNode.
NameNode хранит изменения в файловой системе в виде журнала изменений,
добавляемого к родному файлу. Когда NameNode запускается, сервис считывает
состояние HDFS из файла образа, fsimage, а затем применяет изменения из файла
журнала. После чего он записывает новое состояние HDFS в fsimage и начинает
обычную работу с пустым файлом правок. Поскольку NameNode объединяет fsimage и
редактирует файлы только во время запуска, файл журнала изменений может со
временем стать очень большим. Другим побочным эффектом большего файла
журнала изменений является то, что следующий перезапуск NameNode занимает
больше времени.

Обновление снимков через SecondaryNameNode.


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

Что делать при перезагрузке NameNode.


Фактически алгоритм перезагрузки должен быть такой же как при запуске. То есть
считываем fsimage и применяем к нему операции из лога (в предположении, что лог
хрнаится на диске).

(Эта часть может быть не совсем корректной, про нее дефолтно лучше не
говорить). Но может быть такое, что по какой-то причине логи хранились в RAM и
пропали после перезагрузки. Вероятно в таком случае нам нужно сделать при старте
дополнительный запрос к SecondaryNameNode, чтобы запросить у нее те логи,
которые она успела достать до перезагрузки NameNode. В таком случае часть логов
все же может пропасть, так как логи отправляются на SecondaryNameNode пачками.
Но так как DataNode периодически отправляют актуальную информацию о себе, то
NameNode должна будет либо автоматически разрешить конфликты, либо отправить
какое-то предупреждение, что в системе проблема.
7) Является ли Hadoop отказоустойчивой системой? Благодаря
чему это достигается? Какие инциденты самые
неблагоприятные для Hadoop и почему?

Комментарии лектора: Рассказать все плюсы и минусы хадупа, чем он хорош и плох
в плане отказоустойчивости, доступности информации. Если потеряли 2/3 машин из
кластера, то 100% начали терять данные {хз мб про то, что обычно репликация с
фактором 3}. Рассказать, что NameNode является узким местом {так как она одна}.
Хадуп чувствителен к нагрузкам на нодах, если не балансировать распределение
данных между датанодами, то может так случиться, что постоянно ждут, когда
освободятся ресурсы на одной ноде

Дополненный ответ:
Hadoop переживает переживает отказы Data Node-ов. Это достигается хранением
резервных копий блоков или Erasure Coding. MapReduce переживает отказы узлов за
счет перезапуска задач. Однако может быть так, что отказ одного Reducer-а требует
перезапуска ВСЕХ Mapper-ов. Самый худший отказ это отказ NameNode, так как она
одна и отвечает за хранение всех метаданных про блоки. Есть разные способы как
пережить ее отказ, но все они не очень хорошие:
1. Регулярные Backup-ы - спасает только от полной потери данных
2. Secondary NameNode - позволяет разгрузить NameNode, а также может
заменить упавшую NameNode. Однако Secondary NameNode требует процесс
инициализации что бы стать основной.
3. Федерация - позволяет иметь разные NameNode для разных подпутей.

8) Что такое Rack Awareness и Replica Placement Policy? Зачем


они нужны?

Комментарии лектора: Реплики блоков в хадупе хранятся сначала в одной стойке два
{вроде часть с его первого занятия} и один в другом датацентре, если есть
возможность. Рассказать про эту схему, зачем это делается и как лучше настраивать

Дополненный ответ:
Rack awareness в hadoop - это знания о расположении DataNode-ов по серверным
стойкам.
Replica Placement Policy - политика расположения реплик данных по DataNode-ам.
По умолчанию:
1. Для маленьких кластеров: 2 реплики на одной машине на разных дисках и еще
1 одна реплика на другой машине.
2. Для больших кластеров: 2 реплики на одной стойке в разных машинах и еще
одна на другой стойке.
Rack awareness вместе с Replica Placement Policy позволяют получать
отказоустойчивость и доступность минимизируя при этом передачу данных по сети.
Передавать данные между стойками дороже чем передавать внутри стойки, однако
сервера внутри одной стойки подвержены коррелированным отказам. По этому
стандартная политика располагает одну копию в той же стойке, на случай отказа
машины, и одну копию в другой стойке, на случай отказа стойки.
9) Что такое YARN? Как он выделяет ресурсы? Что такое
очереди?

Комментарии лектора: Yarn - ресурс менеджер. Рассказать про контейнеры ярна, про
то как он мониторит выделение ресурсов, как происходит распределение по очередям,
способы выделения ресурсов

YARN - ресурсный менеджер в Hadoop, в его зону ответственности входит выделение


ресурсов кластера под ваши задачи и их планирование. Единица выделения ресурса в
YARN - это контейнер, который представляет собой набор hardware-ресурсов (vCPU,
RAM, диск, сеть, тд). На один контейнер может приходиться только одна
задача. У контейнера есть конфигурация по квотам на каждый ресурс, на основе
которой выделяется n контейнеров в кластере, исходя из доступных в нем ресурсов.
Например, при конфигурации контейнера в 1 vCPU, на кластере из 3 машин с
четырехъядерным процессором на каждой, можно создать 12 контейнеров.

Несмотря на статичную конфигурацию контейнера, YARN умеет выбирать


различные стратегии выделения ресурсов, исходя из их утилизации:

1. Наивный подсчет контейнеров (container count). В таком случае, планирование


происходит исключительно по числу свободных контейнеров, вне зависимости от
степени утилизации ресурсов кластера.

2. По степени утилизации CPU (fair CPU-bound). При такой стратегии YARN смотрим на
общее потребление CPU кластера, и может добавлять задачи до тех пор, пока
улитизация не достигнет 100 процентов, либо мы не упремся в предел по RAM.
(например, если задача использует 10% CPU кластера при 12 контейнерах, мы
условно, считаем, что занято ceil(0.1 * 12) = 2 контейнера)

3. По степени утилизации RAM (fair RAM-bound). Аналогично пункту выше, только


смотрится на утилизации RAM.

В целом, стратегия, основанная на RAM более безопасная, так как меньше шансов,
что произойдет какой-то segFault или что еще. Но в зависимости от специфики задачи
может использоваться как одна стратегия, так и другая.

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

1. Наивное ожидание завершения предыдущей задачи (hadoop v1). По очевидным


причинам, крайне неэффектино.
2. Ожидание освобождения стольких контейнеров, сколько требуется следующей
задаче. Все еще присутствует простой, но уже куда лучше 1 способа,
используется по умолчанию. (пример: занято 11 контейнеров из 12, висит
задача на 4 контейнера => ждем, пока заняты будут только 8 контейнеров,
потом планируем задачу)
3. Начало исполнения части задачи сразу при освобождении хотя бы какого-то
количества ресурсов, и постепенное увеличение потребления ресурсов
задачей. С данным подходом проблема, что новая задача может отбирать
ресурсы у старой в случае падения каких-либо контейнеров при исполнении
старой задачи.
Перейдем к рассмотрению очередей:

Очереди решают проблему обеспечения гарантированной доли ресурсов для


некоторого пулла задач (например, продакшена). Есть следующие параметры очереди:

1. Гарантия по минимальному количеству контейнеров


2. Максимальное возможное число контейнеров, выделенных на очередь (max
capacity)
3. Максимальное возможное число контейнеров на одну задачу в очереди (max
capacity per job)
4. Приоритет очереди (очереди с высшим приоритетом исполняются раньше)

При появлении задач из более приоритетной очереди им могут быть выделены


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

Бонус: есть yarn distributed console для просмотра и записи логов ярна.

10) Как устроен Parquet?

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


что он файл делит на строчки, строчки делят на блоки, дальше эти блоки на бакеты, в
каждом бакете отдельно колонка хранится

Красивая фраза для вступления: "Parquet - это колоночно-ориентированный формат


хранения данных, изначально созданный для экосистемы hadoop".

Строение данных в файле.


Сначала разбиение "по строкам" на row group (единица для MapReduce задач), далее
на поколоночные блоки (column chunk) для распределения IO операций. Так же
колонки разделяются по страницам (page) для распределения кодирования и сжатия.
Зачем такое строение? Большинство реляционных баз данных плохо работают со
сложными структурами данных. Parquet же адаптирован под сложные форматы
(пример с лекции: если каждая колонка - структура, то блоки будут соответствовать
полям => удобно доставать отдельные данные). Из-за колоночного строения
ускоряется работа с отдельными данными (можно доставать только необходимые
колонки).

Метаданные.
"Киллер фича" Parquet в том, что у него очень содержательный header, в котором
много метаинфы. Есть три типа метаданных: о файле, о колонке и о странице
(подробнее). Parquet явно отделяет метаданные от данных для возможности разбивать
колонки на разные файлы или иметь один файл с метаданными, ссылающимися на
разные файлы данных. Метаданные пишутся после данных для single pass записей.
При чтении сначала берутся метаданные нужных колонок, которые потом
последовательно считываются.
Parquet vs Orc: Orc примерно так же устроен, только нет деления на chunk (=> хуже со
сложными форматами данных работает).

Плюсы/Минусы.
Плюсы:
- По сути это просто файлы => легко работать (перемещать, бэкапить, реплицировать)
- Колончатая структура для эффективности работы с данными
- Эффективное хранение с точки зрения занимаемого места (не говорите, если не
сможете объяснить почему :) )
Использование формата Parquet позволяет лучше сжимать данные, поскольку они
более однородны. Экономия места очень заметна в масштабах кластера Hadoop.

Минусы:
- Колончатая структура требует аккуратности с типами данных и со схемами
- Нет транзакций, тк по сути это не БД, а просто файлы

11) Что такое MapReduce? Какие этапы MapReduce задачи есть


в Hadoop?

Комментарии лектора: Рассказать про парадигму мапредьюса. Зачем нужен Map,


зачем нужен Combiner, зачем нужен Shuffle, Sort, Partitioner. Что можно делать с
МапРедьюс и почему не подходили старые способы распределенных вычислений,
такие как с мьютексами, треды

Input делится на блоки, желательно (и так чаще делают) чтобы блок лежал на той же
ноде где и mapper
Mapper (контейнер) выполняет работу над своим блокам и выдает пару (key, value).
Бередает вывод combiner_у.
Combiner берет и объединяет вывод mapper_а по ключу, чтобы уменьшить нагрузку на
перессылку данных ноде, где крутится reducer.
Partitioner решает на какой reducer лучше отправить вывод после combiner_а.
Shuffle отправляет данные на нужную ноду. Также можно сгруппировать данные по
ключам и например, отправлять данные с ключами A-K первому редьюсеру, остальные
другому.
Sort сортирует по ключам, чтобы reducer быстрее обработал
Reducer (контейнер) склеивает вывод после этапа map.

Количество reducer_ов можно задавать самим, либо hadoop сам посчитать сколько
нужно. Также можно настроить, что не надо ждать когда этап map завершиться
полностью, а уже отсылать данные reducer_у.

Дополнительно после завершения задачи map нода может сохранить на диск данные
обработки. Используется для того что если ноды упала, не надо ждать делать еще раз
этап mapm а можно просто считать с диска. Обычно сохранение на диск делается
параллельно с отправкой reducer_у( если делается конечно).

Минусы старых способов:


1. Об отказах должен заботиться разработчик
2. Потоки сильно связаны
3. Отказоустройчивость у mapreduce лучше
4. MapReduce позволяет запустить задачу на большом количестве нод

12) Что такое Shuffle, Partitioner и зачем нужна сортировка? Что


означает «все ждут одну задачу»?

Комментарии лектора: Почти такой же как предыдущий вопрос, здесь больше упор на
мапредьюс задачи. Более глубокое устройство мапредьюс. Зачем надо
переопределять Partition, какие есть способы для Shuffle

Расширенная схема MapReduce в Hadoop:


Shuffle - процесс пересылки пар (Key, Value) из Mapper’ов на разные Reducer’ы.

Partitioner - модуль внутри той же ноды, что и Map, который определяет, на какой
именно Reducer надо отправить пару (Key, Value) в зависимости от Key.

Sort - происходит на ноде Reducer’а для того, чтобы все пары с одинаковым Key
лежали последовательно. Это позволяет быстро и удобно объединять (суммировать в
случае задачи WordCount) Value из пар с одинаковым Key.

Чаще всего Partitioner вычисляет номер нужно Reducer’а как hash(key) %


reducerCount. Partition можно переопределять в зависимости от решаемой задачи.
Самая главная возможная оптимизация - оставление данных на той же ноде, чтобы не
приходилось их отправлять по сети. Например, если ключ состоит из 2 частей - имени
пользователя и посещенной им страницы, а все ключи с одним именем пользователя
изначально лежали в одном блоке входных данных.

Также может случиться ситуация, когда на один Reducer придёт очень много данных и
он взорвётся. Это значит, “все ждут одну задачу”, с точки зрения данных это
называется dataSkew (перекос в распределении данных на редьюсеры). Например, в
задаче WordCount, если в изначальных данных будут разбросаны слова с таким
итоговым распределением: {(“hello”, 10), (“world”, 100), (“и”, 1000000000)}. Для решения
такой проблемы, если мы знаем примерное структуру входных данных, можно
посолить ключ “и”, и сделать из него, например, “и” + rand(10), на этапе Partitioner. А
затем, либо вручную, либо запустить ещё раз MapReduce, и объединить все пары с
ключем “и” в один снова.

13) Какие плюсы и минусы парадигмы MapReduce и ее Hadoop


реализации?

Комментарии лектора: Рассказать почему на мапредьюсе проще писать код, чем во


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

До MapReduce:
- До MapReduce существовал web-crawler Apache Nutch, который хорошо
справлялся с задачей на одной машине, однако не мог решать задачи
параллельно;
- Часто приходилось масштабироваться вертикально, на больших серверах -
экспоненциальный рост стоимости.

Плюсы MapReduce:
1) Высокая масштабируемость: можно гибко масштабироваться горизонтально на
множестве серверов с виртуальным разделением ресурсов;
a) В контексте Hadoop: в связке с YARN организует контейнеризацию
доступных ресурсов как пары vCPU + RAM, в дальнейшем контейнеры
динамически раскидываются между Job’ами;
2) Снижение стоимости обработки больших данных и входного порога: в
MapReduce кластере может использоваться commodity аппаратного
обеспечения, нет специфических требований к используемому железу
a) В контексте Hadoop: сам Hadoop - open-source решение в Apache - его
код выложен как opensource проект, при необходимости его можно
доработать/взять за основу своего решения;
3) Отделение управления ресурсами от выполнения задач (причина, почему
MapReduce упростил написание кода): MapReduce может служить абстракцией,
в которой описываются этапы вычислений без явного указания разделения
ресурсов на каждом этапе - не нужно беспокоиться за выделение памяти,
синхронизацию, concurrency;
a) В контексте Hadoop: не нужно переопределять все этапы MapReduce
всегда, можно пользоваться стандартными реализациями,
представленными Java-классами;
4) Отказоустойчивость: MapReduce может продолжать выполнение даже в случае
падения executor’ов.
a) В контексте Hadoop: при падении executor’ов Hadoop может как
повторно провести вычисления, так и воспользоваться оставшимися на
mapper’ах результатами(если они не завершились)/загрузить
промежуточные данные с HDFS.

Минусы MapReduce:
1) Решает ограниченный спектр задач: не все задачи хорошо распараллеливаются
или связаны с графами. Порядок операций в парадигме фиксируется, это
отнюдь не везде нужно;
2) Когда нужно большое количество взаимодействий между executor’ами: кажется,
Hadoop плохо подходит для задач, в которых, например, нужны частые
коммуникации между mapper’ов/reducer’ов друг с другом;
3) Плохо подходит для real-time обработки данных: вычисления медленные, есть
передача больших объёмов данных по сети:
a) В контексте Hadoop: медленный этап shuffle, много записей в HDFS,
накладные расходы на репликацию;
4) Тяжело справляется со сложными JOIN: JOIN с множественными комплексными
условиями спокойно способны свести сложность к квадратичной, что в
контексте множества записей на диск и передачи по сети усугубляет ситуацию;
5) Нет поддержки ACID и транзакций: обеспечение атомарности транзакций
затруднено сложной распределённой архитектурой, не подходит для
OLTP-решений.

Дополнительные плюсы конкретно Hadoop реализации:


1) Отказоустойчивость, репликация: Hadoop старается реплицировать данные на
разные диски одного и того же узла + докладывает файлы на ещё
дополнительный узел (на лекции 1 был пример);
2) Гибкость: Hadoop не ограничивает виды данных, с которыми он работает.

Минусы Hadoop-реализации:
1) Накладные расходы: По умолчанию Hadoop довольно часто делает записи в
HDFS, присутствует overhead на этапе shuffle за счёт передачи данных по сети;
2) Name Node - узкое место: т. к. NN хранит данные о расположении блоков
файлов и принимает запросы, её отказ способен положить систему;
3) Неэффективная работа с множеством маленьких файлов: Hadoop начинает
тормозить, когда его заваливают мелкими файлами.

Плюсы Java по сравнению с C++:


1) Снижение общей сложности кода за счёт автоматической сборки мусора,
типобезопасность лучше, чем в C++;
2) Кросс-платформенность, единый API на различных операционных системах за
счёт использования Java Runtime Environment (JRE) и соблюдения требований
по унификации со стороны Java-платформы;
3) Наличие огромного количества библиотек, фреймворков для
enterprise-приложений с богатой инфраструктурой и множеством интеграций;
4) Наличие стандартного пакета java.util.stream для обработки данных c
декларативным синтаксисом, поддержкой ленивых вычислений:
Пример:
int sum = widgets.stream()
.filter(w -> w.getColor() == RED)
.mapToInt(w -> w.getWeight())
.sum();

14) Что такое распределенный кэш в MapReduce? В каких


задачах он используется?

Что это?
Распределенный кэш в Hadoop это механизм, который используется для копирования
небольших файлов или архивов необходимых для вычислений на рабочие узлы.
Файлы в кэше read-only

Когда мы запускаем любое задание, Hadoop копирует файлы, указанные в параметрах


-files, -archives и -lib jars, в HDFS. Перед запуском задачи NodeManager копирует
файлы из HDFS на локальный диск (то есть в кэш)

Кроме того, YARN NodeManager поддерживает счетчик ссылок для количества задач,
использующих каждый файл в кэше. Перед запуском задачи этот счетчик
увеличивается, а после завершения уменьшается. При достижении 0 файл можно
удалять, потому что он больше не потребуется.

Когда размер кеша достигает дефолтных 10Gb, то файлы удаляются в порядке от


наиболее старых.

Плюсы
1. Позволяет распространять сложные типы файлов, такие как jar и различные
архивы
2. Обеспечивает консистентность, никакой процесс не может изменять файл в
кеше, пока этот файл используется
3. Кэш отказоустойчивый, потому что файлы хранятся на многих узлах

Минусы
1. Данные нельзя изменять
2. Предназначен для небольших файлов
15) Как работает HashJoin/ReduceSideJoin? В чем отличие
Map-Side Join и Hash Join? Когда какая стратегия Join’а
применяется?
В hadoop существует 3 основных вида джойнов:
1. Map Side Join используется, когда одна из входных таблиц маленькая и
помещается в память.
a. Каждый mapper загружает маленькую таблицу в память и строит по ней
HashTable
b. Обходит свою часть большой таблицы и для каждого значения ищет пару
в хеш-таблице
c. Записывает полученные пары в ответ
Этот алгоритм работает быстро, но его можно использовать только если одна из
таблиц маленькая.
2. Reduce Side Join = Hash Join = Shuffle Join - стандартный алгоритм,
используемый для джойнов, он тяжелый, медленный, но работает всегда.
a. Маппер добавляет к паре (key; value) идентификатор таблицы, чтобы
получилась тройка (key, table_id, value) и передает эти данные на shuffle
b. Shuffle группирует данные только по ключу и передает на reducer-ы
c. Reducer сортирует данные по table_id; затем сплитит их по table_id,
чтобы отделить данные из разных таблиц друг от друга; делает cross join
данных из разных таблиц и записывает ответ.
3. Merge Join = Sort Join - используется, если обе таблицы отсортированы по
ключу. Применяется алгоритм 2-х указателей.

Когда и что используется?


Map Side Join используется, когда одна из таблиц маленькая и помещается в
оперативную память, во всех остальных случаях (по дефолту) используется Hash Join
= Reduce Side Join

16) Как на MapReduce решается задача поиска компонент


связности графа?
Комментарии лектора: Рассказать алгоритм, то что делается на последовательности,
важно не забыть сказать критерий остановки

Для более формальной постановки будем считать, что данные нам даны как в дз по
БФС. То есть построчно записаны пары чисел, которые задают концы ребер. В конце
хотим получить пары чисел - номер вершины и id компоненты, в которой она
находится.

Если кратко описывать решение, то будем каждый раз брать минимальный номер
компоненты среди соседей. Так мы для каждой компоненты фактически сделаем ее
номер равным минимальной вершине из этой компоненты. Потратим на это не больше
Н итераций.

Подготовительная фаза

Для начала преобразуем одной операцией MapReduce данные к удобному формату


“vertex_id component_id neighbors”. Номер вершины, номер компоненты и соседи этой
вершины, записанные через запятую. Сделать это можно для каждой пары из входных
данных отправляя на редьюсер 2 пары, в одной на как ключ первая вершина, как
значение вторая и аналогично для второй пары, но в другом порядке. Таким образом
просто сгруппируем для каждой вершины всех ее соседей (можно еще дубликаты
почистить).

На первой итерации как component_id используем vertex_id.

Основная фаза

Теперь будем в маппере считывать строку с вершиной, компонентой и соседями.


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

В редьюсере среди всех значений, где вершина из ключа не равна вершине из


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

Также увеличим глобальный счетчик, если значение новой компоненты не совпало со


значением предыдущей.

Восстановление ответа

В качестве критерия остановки будем смотреть равна глобальная переменная 0 или


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

В качестве последней итерации можем просто выкинуть из последнего


промежуточного файла соседей (еще одна MapReduce итерация как в прошлый раз, но
где мы не выводим соседей в файл). Таким образом в итоговом файле мы для каждой
вершины из одной компоненты номер компоненты будет одинаковым.
17) Могут ли мапперы обмениваться информацией между
собой? А редьюсеры?

Комментарии лектора: Снова рассказать про парадигму мапредьюса. Сказать, что не


могут обмениваться информацией, сказать почему нет {видимо из-за архитектуры, что
если нам нужно взаимодействие маперов, то поч не отправить на одинаковый
редьюсер, но хз это мой кукарек}

18) Что такое HIVE? Какие у него компоненты?


Пояснения нет

19) Что такое TEZ? В чем его отличие от MapReduce?

Комментарии лектора: Надо рассказать о том, что TEZ это про направленный
ацикличный граф вычислений и можно в отличии от мапредьюса не обязательно все
материализовывать в HDFS результат мапредьюс стадий + можно передавать данные
внутри ноды {мб это про то, что делаем отложенные операции, а не записываем сразу
на диск, но мне казалось, что такое спарк в первых версиях делал}. Собственно
рассказать про фичи TEZ и почему он появился

20) Как можно оптимизировать Hive запросы?

Комментарии лектора: Есть какой-то чеклист в чате {вероятно вот это


https://docs.google.com/document/d/1SwKa_Gn-xPyurK4f7ww6ZIe5NJnFZgJJ5i2361AgW3
s/edit?usp=sharing}

Нулевой шаг - определить, во что мы упираемся. Возможные причины:


a) Использование анти-паттернов при написании запросов;
b) Нехватка ресурсов:
i) RAM;
ii) CPU;
iii) Диска;
iv) Hadoop-контейнеров.

Если тормозит операция:


1) Упираемся ли в диск. Смотрим на дашборде машин кластера - проверяем, что
нет нод на которых выполняются наши задачи и у них забиты IO.
a) Фикс: использовать сжатые форматы работы с данными - например,
ORC или Parquet. При этом помнить, что увеличится нагрузка на CPU.
2) Упираемся ли в контейнеры. Причиной могут быть combiner’ы с квадратичной
асимптотикой, что может вести к зависаниям.
a) Фикс 1: Увеличить количество мапперов/уменьшить количество данных
на одного маппера. ( изменение размера сплита ).
b) Фикс 2: Увеличить количество reducer’ов ( работает, только если Hive не
решил, что он самый умный. Например, в sort Hive ставит 1 reducer).
c) Фикс 3: Посмотреть на смещенность данных на этапе Combine/Reduce.
Если есть, то выкинуть выбросы и разбить вычисление на куски
(отдельно обрабатываем выбросы, отдельно обрабатываем нормальные
данные, как вариант - введение фиктивный ключей, т.е. Ключ у
монстрключа = ключ + ‘_’ + RND(100) ).
3) Узкое место - CPU или Оперативка. Если и то, и другое, можно попробовать
увеличить степень параллельности и степень партиционирования данных.
a) При наличии Spark запустить локальную эмуляцию и посмотреть
расходы;
b) Помогает ли увеличение оперативки доступной для JVM. Если помогает,
то была 100% оперативка - оптимизируем ее.
c) Тротлинг.
4) Использовать COUNTERS - служебные счётчики, которые есть у задач. По
умолчанию автоматически считают такие показатели, как количество записей,
размер входных данных. Но можно добавлять свои - например, записывать
затрачиваемое на операции время.

Способы подсказать HIVE, как сделать операцию эффективнее:


1) Подзапросы. Так, например, Hive сможет понять, что таблица в подзапросе
маленькая и применить MapSideJoin, что позволит загрузить её в RAM;
2) Разбиение на логические куски. (явная реализацию оконных функций)
3) Явное указание диапазонов бакетирования и партиционировани;
4) Использование сортированности данных. Так, фильтр Блума в Parquet может
помочь пропустить лишние блоки;
5) Не использовать индексы, т. к. даётся достаточно мало контроля над
взаимодействием Hive с ними;
6) Явно указать нужные колонки на моменте чтения таблицы, избегать SELECT *
там, где в этом действительно нет необходимости;
7) Манипулировать параметрами MapSideJoin.

Анти-паттерны работы с Hive:


1) Не стоит без причины использовать движок MapReduce, в том числе из-за того,
что он пишет в HDFS чаще, чем TEZ или Spark. MapReduce стоит использовать,
если:
a) Операция сложная и нестабильная;
b) Данные огромные и TEZ/Spark на них застревают;
2) Не сохраняйте production данные в тексте - это излишняя нагрузка на диск;
3) Не используйте динамическую типизацию и схематизацию, это заставит Hive
заниматься типизацией при чтениях;
4) Не используйте динамическое партиционирование (по информации 2021 года
давности);
5) Не используйте в Hive метапрограммирование.

21) Почему Hive не поддерживает ни один из стандартов SQL?


Каких инструкций ему не хватает? Почему?

Комментарии лектора: Вопрос про то, что в Hive нет апдейтов, нет удалений, потому
что хадуп в принципе аппенд онли {не оч понял, в HDFS точно можно удалять файлы,
но мб где-то в лекциях про это говорится}. Он еще что-то сказал, что директивы update
и delete под собой скрывают директивы полного удаления и перезаписи {тут надо
посмотреть лекции, я не оч понял, что имеется в виду}. Можно упомянуть некоторые
оконные функции, которых нет в Hive из-за сложности их реализации и из-за
отсутствия индексов
22) Хорошая ли идея подключить Hive к BI инструменту?
Почему? Какие альтернативы?

Комментарии лектора: В среднем идея не очень хорошая, надо объяснить почему

Почему она плохая, во-первых потому, что Hive не поддерживает часть стандартных
sql операций, в результате чего, если подключаться через jdbc - есть шанс того, что BI
сгенерирует запрос, который hive не сможет обработать.

Но это не единственная проблема. Гораздо большая проблема - это время отклика. BI


инструменты очень часто делают запросы к источникам данных. Чтобы получить
список доступных значений, чтобы отреагировать на изменение какого-то фильтра,
чтобы перерисовать график. При этом время отклика hive оставляет желать лучшего,
даже в том случае, когда мы используем не MapReduce, а Tez или Spark в качестве
движка для запросов.
(с) Архимаг

23) В чем разница между Internal и External таблицами в Hive?

Комментарии лектора: Интернал таблицы менеджерятся самим хайвом, а экстернал


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

HiveMetaStore – часть Hive, сохраняет схему виртуальной базы данных.


Компании часто используют только компонент HiveMetaStore без остального Hive.
В Hive существует 2 типа таблиц:
● External
- не управляются Hive-ом
- в MetaStore сохраняется информация о данных таблицах
- не поддерживают ACID транзакции
● Internal
- создаются и используются только через Hive
- любые события с ними идут через Hive
- в MetaStore сохраняется информация о данных таблицах
- поддерживают ACID транзакции

Важно: любая таблица в Hive это всегда папка!


Пример:
При выполнении DROP table, если table является External таблицей, то удалится
только информация о ней из MetaStore, при этом данные в Hadoop-е останутся. В
случае, если table является Internal таблицей, то помимо удаления записи из MetaStore
будут также удалены данные из Hadoop-а.
Также Hive во время работы с таблицами собирает разные статистики для более
быстрого ответа на запросы. Для Internal таблиц ничего руками делать не нужно, а для
External таблиц нужно вручную выполнять запуск обновления статистики.

24) Что такое партиционирование? Как его реализует Hive?


Почему оно важно в BigData?

Партиционирование (partitioning) — это разбиение больших таблиц на


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

Достоинства:
● Партиционирование помогает оптимизировать некоторые типы запросов
к СУБД. В особенности это касается запросов с WHERE. Например, если
таблица партиционирована по значению колонки country, и приходит
запрос с “WHERE country == “RU” ”, то для ответа на запрос понадобится
прочитать содержимое только одной директории, в которой лежит
меньше данных, чем во всей таблице;
● Также партиционирование может помочь для запросов с GROUP BY, где
группировка происходит по тем же колонкам, по которым происходило
партиционирование, так как данные по сути уже сгруппированы, и запрос
можно распараллелить, выполняя его одновременно для каждой из
директорий со сгруппированными данными;
● Можно эффективнее распределять данные по дискам, так как
директории, получившиеся в результате partitioning’а могут храниться в
разных местах.
Недостатки:
● Чем больше партиций, тем больше образуется файлов и директорий, и
тем труднее хранить и поддерживать связанные с ними метаданные;
● Некоторые запросы будут наоборот выполняться менее эффективно
(например, SELECT с WHERE по НЕ партиционированным колонкам), так
как придётся обходить множество директорий вместо одной, а также
задач в MapReduce процессах будет больше.

В Hive любая таблица представляет собой директорию (даже если её загрузили


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

В Hive созданы инструменты для удобной работы с партиционированием – при


создании таблицы можно использовать ключевое слово PARTITIONED BY и
указать колонки, по которым будет производиться партиционирование.
Вставить данные в уже партиционированные таблицы можно, используя
динамическое и статическое партиционирование:
1) Динамическое партиционирование – это когда при вставке данных
указывают только имена колонок, по которым хотят произвести
партиционирование новых данных, например

INSERT OVERWRITE TABLE CUSTOMERS PARTITION (country)

SELECT NAME, EMAIL, PHONE, COUNTRY FROM SOURCE_CUSTOMERS;

И тогда Hive сам выбирает, по каким значениям делать


партиционирование, что помогает сэкономить время, если пользователю
не важно, каким в итоге будет разбиение
2) Статическое партиционирование – это когда пользователь сам задаёт, по
каким значениям делать партиционирование, например

LOAD DATA IN '/testdata.txt' INTO TABLE CUSTOMERS PARTITION(COUNTRY='US');

Благодаря такому методу можно самостоятельно задать итоговое


разбиение, подстроив его под свои нужды так, чтобы запросы в будущем
выполнялись более эффективно.
Чтобы узнать, какое разбиение в итоге получилось, можно запустить команду
SHOW PARTITIONS.

25) Что такое GreenPlum?


Поделка поверх Postgres, использует несколько нод постгри + мастера над ними.
Разбивает запрос на простые части (по сути Map’ы), которые делегируются рабочим
нодам и сложную часть (по сути Reduce/Sort) которые может выполнять только мастер,
что автоматически делает его боттлнеком всей системы.
Плюсы: поддерживает транзакции и Postgres compatible SQL
Минусы: всё остальное (забудьте про сливу и больше никогда не вспоминайте)

26) Что такое Vertica?


Шардированная реплицированная колоночная СУБД, состоит из реплицированных
шардов поверх которых имеются транзакции. Все ноды гомогенны, поэтому скейлить
её можно до бесконечности, каждая нода при этом хранит на себе какие-то реплики
каких-то шардов + исполняет запросы. Также есть resource management для различных
пользователей (на случай если аналитик решит положить прод)
Почти идеальная база для OLAP, но не опенсорс и требует лицензию если вы хотите
больше трёх нод или больше ТБ диска

27) Что такое ClickHouse?

Комментарии лектора: Рассказать за 15 минут как устроены эти распределенные БД.


В чем между ними разница, какие плюсы и минусы. В каких случаях какие можно
выбрать

Лекция: тута

ClickHouse - это колоночная аналитическая СУБД. ClickHouse не поддерживает


классический SQL, имеет свой диалект с особенностями.
Фичи:
● Большое кол-во оптимизаций под разные типы данных, например, векторные
вычисления.
● Есть оптимизации по хранению данных, с одной стороны позволяют более
эффективно складывать данные, но при этом может быть ситуация, когда
данные будут, например, долго INSERT’ится.
● Встроенные структуры, такие как массивы и словари.

Минусы:
● Лектор еще упомянул, что в CH отсутствуют UDF, но вроде бы в клике что-то
подобное уже есть, вот ссыль на доки: тык (возможно недавно выкатили).
● Словари подгружаются на лету, но грузятся в оперативную память и могут
сильно её отъедать.
● Синтаксис SQL сильно ограничен в плане поддержки UPDATE/DELETE.
● Среди оптимизаций есть

Вывод: CH нужен если есть много данных и нужно что-то быстро просмотреть,
проанализировать и нарисовать. В то же время плохо работает с запросами
JOIN/UPDATE/DELETE, в случаях если данные нужно часто обновлять или джойнить,
может быть лучшим решением заюзать что-то другое.

Не авторский комментарий:
JOIN: после вот этого коммита товарища Скворцова
https://github.com/ClickHouse/ClickHouse/pull/38191, плохость джоинов кликхауса ушла в
прошлое
UPDATE/DELETE: При использовании движков семейства CollapsingMergeTree и
VersionedCollapsingMergeTree можно выполнять update и delete по цене INSERT
Главная проблема кликхауса это отсутствие транзакций, то есть нельзя конкурентно
делать update/delete as is что действительно создаёт некоторую головную боль.
На текущий момент нет вообще ни единой причины использовать не ClickHouse если у
вас нет денег на лицензию Vertica и вам не нужны транзакции (если нужны стоит
посмотреть в сторону CockroachDB)

28) Что такое Spark? Из каких компонент состоит? Какие API


есть?

Комментарии лектора: Спарк система выполнения задач распределенная, то что


может подключится к любому источнику. Коннектов очень много. Рассказать про спарк
драйвер, про спарк экзекьюторы, про способы подключения к спарку

Лекция тут

Spark (Apache Spark) - опенсорсная система для аналитики (analytics engine) больших
данных. Представляет из себя только саму систему для надежного хранения и
исполнения запросов, для работы ему требуется распределенное файловое
хранилище и система менеджмента кластера. Поддерживается богатый выбор
приложений для этих задач и собственный Spark Cluster. Является очень популярным
решением для компаний среднего размера. Внутри поддерживает исполнение
ациклических графов задач и стриминговый режим. Написан на Scala

Пример: есть здесь, для кластеров приводится простое развертывание standalone,


поверх Apache Mesos, Kubernetes, Amazone S2, YARN (HDFS). Для файлов форматов
очень много: https://spark.apache.org/docs/latest/sql-data-sources.html.

Краткая история:

Map Reduce между этапами используются тяжелые операции:

Этап Операции

Map Чтение с диска

Combine Передача по сети

Shuffle Передача по сети, часто запись на диск

Reduce Запись на диск, репликация

Также MapReduce требует строго линейное исполнение, что не всегда удобно - частый
пример ML и итеративное улучшение.

2009 год - MIT, прототип Spark

2012 - проект попадает в Apache (Apache Spark), изначально надстройка над HDFS

Структура (с лекции):

Устройство в версии 1.0: лекция с 22 минуты, скорее всего не нужно

Устройство в версии 2.0: лекция с 35 минуты

Spark Driver - мастер сервер, раздает задачи на исполнение к Spark Executors, следит
за выделенными ресурсами и созданными экзекъюторами, обрабатывает запросы
клиентов и преобразует их в другой формат, является возможной точкой отказа, но в
новых версиях есть интеграция с Zookeeper (на лекциях об этом не было) и проблема
надежности вроде бы решается. Масштабирование все еще ограничено одним
мастером.

Execution Node - основной узел для исполнения, в ранних версиях - Data Node, в
актуальной называется Worker Node. Запускает один или более Spark Executor.
Data Node - слой хранения данных, в ранней версии Hadoop, в любой более-менее
актуальной - отдельный слой, например, локальная БД в тестах или Amazon S3 в
современных облачных приложениях. Обычно Data Node использует дешевые сервера
с большим диском и малым CPU, а Execution Node - больше CPU и RAM

Spark Executor - выполняет задачи с явным указанием обращения с результатом


Spark Executor: действия с результатом

Сохранить в оперативной памяти

Сохранить в RAM и HDD

Сохранить на HDD

Перераздать в другие ноды-экзекьюторы или ноды-хранилища(shuffle)

Отдать на Spark Driver

Сохранить в destination

Для старой архитектуры HDD - сохранить в локальный диск, в новой - HDD это
отправка на Data Node слой. Сохранение в RAM и HDD пытается положить данные в
RAM, если не получается - HDD.

API:

API Доки Краткий комментарий

Scala тык Нативная и сама широкая и эффективная


версия API

SQL тык Требует Hive-metastore (настройка таблиц),


малоэффективен для сложных запросов,
поднятие сервера SQL запросов отдельно

Python тык Не эффективен при записи в UDF (из-за


лишнего слоя абстракции и
сериализации/десериализации между Python и
JRE), в остальном похож на Scala API,
продвинутая интеграция с Pandas

Java тык Из-за того, что Spark написан на Scala

R тык Не очень поддерживается и скорее deprecated

При исполнении запросов строится граф вычислений и считается лениво, подробнее


про это билет 32
Все API работают в интерактивном режиме (shell-like), для Scala есть “компилируемый
режим” - не совсем компиляция, преобразование в Scala-скрипт с использованием
аналитики и оптимизаций.

29) Почему Spark быстрее MapReduce?

Комментарии лектора: Почему спарк в некоторых местах более гибкий, чем


мапредьюс

Краткое сравнение:
Критерий Spark MapReduce

Модель вычислений DAG + ленивые Только MapReduce


вычисления

Интерфейс SQL или низкоуровневый Надо писать код или Hive


со всеми своими
проблемами

Память Может писать в Только работа с диском


оперативку или на диск

Формат данных Поддерживает Только батчи


стриминговые данные

Отказоустойчивость Перезапускает операцию Сохраняет большинство


на экзекуторе с нуля промежуточных
результатов на диск

File System Почти любая, в том числе Привязано к


удаленная из облака имплементации
(например, HDFS)

Цена Выше, так как более Дешевле, disk-heavy


CPU-heavy

Основные преимущества - более гибкая графовая модель вычислений и поддержка


вычислений в оперативной памяти - кэширование. Если данные на Spark Executor не
помещаются в память, работа замедляется. Также Spark сильно страдает от частых
запросов в мастера (Spark Driver) с результатами промежуточных вычислений.

Spark Driver может заметно оптимизировать DAG и распределять ресурсы, в то время


как в версии Hadoop MapReduce используется много статических параметров при
запуске всей задачи в целом.

“Many organizations run Spark on clusters of thousands of nodes. The largest cluster
we know has 8000 of them. In terms of data size, Spark has been shown to work
well up to petabytes. It has been used to sort 100 TB of data 3X faster than Hadoop
MapReduce on 1/10th of the machines, winning the 2014 Daytona GraySort
Benchmark, as well as to sort 1 PB. Several production workloads use Spark to do
ETL and data analysis on PBs of data.” (источник)
Можно посмотреть, когда Hadoop эффективнее Spark, но это, вроде, не спрашивают
(Блог IBM). Если кратко, то для конкретно своей модели задач Hadoop в целом не
сильно хуже Spark, но требует более дешевых устройств (disk-heavy и лучшее
fault-tolerance)

Для примера на преимущества гибкой модели - машинное обучение и поддержка


стриминговых данных. Для классических MapReduce задач можно посмотреть блог, как
Spark обогнал Hadoop на простой задаче сортировки. Кратко - использование
сторонней быстрой файловой системы от Amazon, более сложные алгоритмы
сортировки, чем в хадупе, кэширование с подгоном размера ключа под размер кэша
(архитектура Spark позволяет добавление подобных модулей), декомпозиция Spark
Driver и Spark Executor, что позволило добавить отдельный сервис-координатор
распределяющий данные, пока на SD происходит сборка мусора.

Не было на лекции: стоит заметить, что для MapReduce существуют улучшения,


перечисленные в статье на странице 7 для итеративных задач, переиспользования
результатов прошлых запусков, self-tuning, но сравнения их со Spark я не искал

30) В чем разница между RDD, DataFrame, DataSet?

Комментарии лектора: Рассказать о представлении данных внутри спарка. И о


развитии между переходом RDD -> DataFrame -> DataSet

Немного истории: в Spark 1 было только RDD. В Spark 2 появился сначала DataSet, а
потом уже DataFrame.

RDD (Resilient Distributed Dataset).


Абстракция, которая описывает данные, лежащие распределенно. Довольно близка к
файлу в HDFS. Одно из отличий в работе с MapReduce в том, что RDD не обязательно
должно быть в самом HDFS, куски могут также находиться локально на машине,
например, на диске.
Проблемы. Если ты разработчик и знаешь свое дело, то в целом RDD тебе и не нужен,
так как ты сам можешь сделать лучше и более приспособленнее под нужную сферу. А
если ты новичок, то RDD не давал особой помощи в работе с данными + некоторые
вещи нужно было делать вручную (например, раскладывать по шардам).

Переход к DataSet.
Разработчики Spark осознали, что в конкретный момент основная целевая аудитория -
не разработчики, а аналитики. => добавляется аналитический движок. Появился
DataSet: фактически то же самое, что RDD, только жестко типизированное.

Переход к DataFrame.
Из-за добавления DataSet в Spark появились проблемы с SQLApi и PythonApi (есть
еще ScalaApi). В итоге появляется DataFrame, который фактически = (RDD +
метаинформация об этом RDD). Отличие от DataSet в том, что DataSet говорил строго
о физическом представлении данных (типизация). В DataFrame уже есть
таблички+схемы (схемы можно взять: из Hive Meta Store/указать руками/из
схематизированного файла типа Parquet).
31) Какие операции поддерживает RDD? Какие типы операций
есть и в чем между ними ключевая разница?

Комментарии лектора: Не ожидается исчерпывающий список команд, которые можно


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

RDD (aka Resilient Distributed Dataset) - абстракция распределенной коллекции


элементов. Поддерживает 2 типа операций:

1. transformation — ленивое преобразование RDD.


2. action — вычисления которые возвращают драйверу какое-то значение.
Вычисляет явно все накопленные transformation.

Примеры transformation:

● map — преобразует каждый элемент функцией


● filter — фильтрует элементы по предикату
● flatMap — map но функция возвращает несколько элементов
● union — объединяет 2 RDD
● intersection — пересекает 2 RDD
● distinct — возвращает RDD в котором только уникальные элементы

Примеры action:

● reduce — использует ассоциативную и коммутативную функцию для того чтобы


посчитать одно значение/статистику с всего RDD.
● collect — возвращает весь RDD
● foreach — запускает функцию для каждого элемента

Так же параллельно RDD поддерживает кеширование. RDD можно пометить как


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

32) Что такое ленивые вычисления и какое отношение они


имеют к Spark?
Ленивые вычисления - это стратегия вычислений в которой обработка откладывается
пока не понадобится результат. Spark, по умолчанию, ленивый обработчик, то есть
когда вы, например, пишите на python API вы на самом деле строите граф
вычислений. Сами вычисления начнутся только тогда, когда вы явно дадите команду.
33) В чем разница между Repartition и Coalesce? Когда что
использовать?
Введение
Дефолтное количество партиций не всегда удобно и эффективно. Кроме того иногда
мы можем хотеть поменять способ партиционирования данных. Это можно сделать
двумя способами: Coalesce(коалеск) и Repartition.
Обе функции, казалось бы, делают одно и то же: преобразуют ваш датасет на
указанное вами количество партиций.

В чем разница?
Представим, что в нашем датафрейме количество партиций равно n (partition.size=n)
Тогда для Coalesce в качестве аргумента мы можем указать число партиций, не
превышающее n.
А в Repartition мы можем запихнуть любое число m.

Как они работают?


Repartition для каждой строчки заново посчитает хеш и возьмет его по модулю числа,
которое вы указали. Тем самым он вызывает пересортировку и полный шафл всех
ваших данных. С помощью Repartition мы можем решать задачи шардирования
данных.
Coalesce работает иначе. Мы не можем увеличить число партиций относительно
текущих, только уменьшить. Поэтому он будет смотреть на каждую строку и смотреть:
если хеш больше нового числа m, то следует эту партицию разослать на других
экзекюьтеров (два варианта: либо вся партиция летит в конкретного экзекьютера, либо
она распределяется между всеми первыми m экзекьютерами; второй вариант
наиболее вероятный, но все зависит от настроек), если же меньше, то все хорошо -
пусть летит на своего экзекьютера. Тем самым, мы двигаем только те партиции,
которые по хешу оказались выше указанного нами числа.

То есть мы можем пересортировать по конкретному ключу все данные с помощью


RepartitionByKey, а в случае Coalesce мы можем уменьшить количество партиций
путем слияния.

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

Когда что использовать?


Пример 1. Данные сильно перекошены (в первой партиции 60% данных, во второй
25%, а оставшиеся 15% распределены между оставшимися 10-ю партициями).
Нужно использовать Repartition, потому что Coalesce будет просто перекидывать все
данные на первые партиции, и глобальная таска по сути будет выполняться только в
одном-двух потоках.

Пример 2. Входные данные разложены файлами по 5 минут, мы обрабатываем день.


Каждый файлик - отдельная партиция. (Всего получается 288 партиций, а
экзекьютеров 100, поэтому мы хотим сократить количество партиций)
Тут напрашивается Coalesce, чтобы слить данные, но нужно следить за тем, чтобы
данные не были сильно перекошены (например низкая ночная нагрузка на сервер).
Возможно, придется использовать Repartition.

Пример 3. Данные по пользователям пошардированы по году рождения. Нам нужно


по полу.
Однозначно Repartition. Потому что при Coalesce в любом случае останутся
нетронутые коалиции (например, люди, родившиеся в 1963 году), в которых будут
представители всех полов.

Пример 4. Ваш код тормозит на этапе Map-операции, хотя она совсем простая (+1
к интовому полю). Мы хотим операцию ускорить, поменять количество потоков.
Все слишком неоднозначно, нужно смотреть на размахивания руками. В виде
конспекта сложно запечатлеть, поэтому оставлю ссылку:
https://youtu.be/u6MMCo_xgqk?t=1779 (можно посмотреть на х2 пару минут)
Итог такой: все сильно зависит от ситуации, Repartition может даже сделать хуже

34) Для чего Spark использует Hive MetaStore?

Комментарии лектора: Для того чтобы работать с данными на хадупе на hdfs как с
таблицами, а не как с сырыми файлами

Hive MetaStore - компонента Hive которая хранит схему и метаданные таблиц


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

Поддерживаемые из коробки базы данных:


● MS SQL Server
● MySQL
● MariaDB
● Oracle
● Postgres

В Spark кроме RDD также поддерживаются такие абстракции как Dataset (жёстко
типизирован) и Dataframe (по сути RDD, вокруг которого написана метаинформация).
То есть, рядом с Dataframe рядом лежит схема о том, что данные табличные, данные в
колонках. Таким образом, с Dataframe можно работать как с обычными таблицами.\

Сфокусируем наше внимание на датафреймах. Один из способов получения схемы


для датафрейма — Hive MetaStore, если он есть.

Кроме этого Spark умеет работать с таблицами из Hive.

Вам также может понравиться