In this repository files are located whose realize Hadoop MapReduce technology on Java!
В этой работе я с одногруппниками в рамках учёбы в университете выполняли задания по "Методам BigData" — так называется сама дисциплина. Эти задания были на тему эффективной обработки данных больших объёмов. Мы изучали инструмент под названием "Hadoop", который используют многие популярные компании, типа, Facebook, Amazon, Yahoo и многие другие коммерческие и некоммерческие объединения специалистов в этой области. Этот инструмент как раз и позволяет очень хорошо и быстро загрузить, обработать и сохранить разные данные на сервера организаций.
Преподаватель у нас по этому предмету А.С. Лебедев — очень умный и талантливый человек; он очень много знает про искусственный интеллект, BigData и про многие другие области математики и IT.
"Методы BigData" преподавались у нас на 4-м курсе 2021–2022 гг. Это действительно полезный предмет, ведь благодаря ему мы узнали многое про организацию хранения и способы обработки Больших Данных.
Мне удалось выполнить три лабораторные работы из пяти в течение этого семестра. Но есть и ребята, которые сделали намного больше и вложили в это дело очень много своего времени и усилий и реализовали все пять или четыре подобные работы. Респект таким трудягам!)
Ниже представлено общее описание этих трёх лабораторных работ, чтобы вы, дорогой читатель, были в курсе всего, что связано с BigData!
- Теоретическое введение
- История и главные черты Hadoop
- Модель программирования MapReduce в Hadoop
- Обработка реляционных данных в экосистеме Hadoop
- Алгоритм HITS и Spark
- Отчёт по второй лабораторной работе
- Список использованной литературы
- Примечание
Мы живем в эпоху, когда объемы данных, с которыми нужно работать ежедневно, превзошли возможности одной сколь угодно мощной вычислительной машины [1]. Большие данные сопряжены не только с двумя фундаментальными проблемами их хранения и обработки, но, что более важно, сложностями в их интерпретации и понимании, как превращать их в конкурентное преимущество. Hadoop заполняет пробел на рынке, предоставляя эффективные средства хранения и управления вычислительными ресурсами для обработки значительных объемов данных. Это распределенная система, которая предлагает способ распараллеливания и выполнения программ на кластере машин. Hadoop был принят такими технологическими гигантами, как Yahoo, Facebook и Twitter для удовлетворения своих потребностей в больших данных, и он продолжает проникать во все отрасли промышленности.
Hadoop — это платформа, которая обеспечивает как распределенное хранилище, так и вычислительные возможности. Первоначально Hadoop был задуман для устранения проблемы масштабируемости, которая существовала в Nutch — краулере с открытым исходным кодом и поисковой системе. В то время Google опубликовал статьи, в которых описывалась его новая распределенная файловая система Google (GFS), а также MapReduce — вычислительная среда для параллельной обработки. Успешная реализация концепций этих документов в Nutch привела к его разделению на два отдельных проекта, второй из которых стал Hadoop — проектом первого уровня Apache.
Собственно, Hadoop — это распределенная архитектура «главный- подчиненный», которая состоит из распределенной файловой системы Hadoop (HDFS) для хранения и MapReduce для обеспечения вычислительных возможностей. Характерными чертами Hadoop являются разделение данных и параллельные вычисления над большими наборами данных. Его хранилище и вычислительные возможности масштабируются с добавлением узлов в кластер, и могут обрабатывать петабайты данных в кластерах с тысячами улов.
HDFS — это компонент хранения Hadoop, распределенная файловая система, вдохновленная статьей о файловой системе Google (GFS). HDFS оптимизирована для обеспечения высокой пропускной способности и лучше всего работает при чтении и записи больших файлов (гигабайт и больше). Для поддержки этой пропускной способности HDFS использует необычно большие (для файловой системы) размеры блоков и оптимизацию локализации данных для уменьшения сетевого ввода/вывода.
Масштабируемость и доступность также являются ключевыми характеристиками HDFS, что отчасти достигается за счет репликации данных и отказоустойчивости. HDFS реплицирует файлы заданное количество раз, устойчив к программным и аппаратным сбоям, а также автоматически реплицирует блоки данных на вышедших из строя узлах.
Как итог этого параграфа, можно обощить, что Hadoop — это технология, использующая множество одновременно работающих компьютеров (серверов или кластеров) для обработки и хранения большого объёма данных. Если вы хотите ускорить обработку или объём памяти, то расширяться вам будет лучше не вертикально, то есть с улучшением качества оборудования самих компьютеров — это весьма дорого по времени и бюджету — а расширяться вам следует горизонтально, иными словами путём увеличения количества машин. У Hadoop есть своя файловая система, которую называют распределённой, или работающей в сразу нескольких компьютерах — HDFS (Hadoop Distributed File System). А обрабатывают эти данные программисты с помощью технологии параллельного вычисления MapReduce, которая работает в два основных этапа, Map и Reduce, и которая включает в себя многопоточность.
MapReduce — модель программирования, ориентированная на обработку данных [1]. Эта модель проста, но не настолько, чтобы в ее контексте нельзя было реализовать полезные программы. Hadoop позволяет запускать программы MapReduce, написанные на различных языках. Все программы MapReduce параллельны по своей природе, следовательно, крупномасштабный анализ данных становится доступным для всех, у кого в распоряжении имеется достаточно вычислительных машин. Достоинства MapReduce в полной мере проявляются в работе с большими наборами данных.
Работа MapReduce основана на разбиении обработки данных на две фазы: фазу отображения (map) и фазу свертки (reduce). Каждая фаза использует в качестве входных и выходных данных пары «ключ-значение», типы которых могут быть выбраны программистом. Программист также задает две функции: отображения и свертки:
map: (k1, v1) → [(k2, v2)]
;
reduce: (k2, [v2]) → [(k3, v3)]
,
где k1
, k2
, k3
и v1
, v2
, v3
— обозначения типов данных ключей и значений
соответственно. MapReduce гарантирует, что вход каждого reducer отсортирован
по ключу. Процесс, посредством которого система выполняет сортировку и
передает выходные данные map в reduce в качестве входных данных, известен как тасовка и сортировка (Shuffle and Sort). На этом этапе те пары «ключ-
значение», у которых ключ совпадает, объединяются:
[(k2, v2)] → (k2, [v2])
,
затем разделяются между экземплярами reduce и сортируются по ключу. Каждый экземпляр reduce получает все значения, связанные с одним и тем же ключом.
Многие задания MapReduce ограничиваются по пропускной способности, доступной в кластере, поэтому передачу данных между задачами отображения и свертки желательно свести к минимуму. Hadoop позволяет пользователю задать комбинирующую функцию, которая будет выполняться для выходных данных отображения:
combine: (k2, [v2]) → [(k2, v2)]
.
Выходные данные комбинирующей функции образуют ввод функции свертки. Так как комбинирующая функция является оптимизацией, Hadoop не предоставляет гарантий относительно того, сколько раз она будет вызвана для конкретной записи выходных данных отображения, и будет ли вызвана вообще. Другими словами, при вызове комбинирующей функции нуль, один или несколько раз функция свертки должна выдавать одинаковый результат.
Технология Hive выросла из потребности в управлении и извлечении информации из огромных объемов данных, ежедневно производимых Facebook в стремительно растущей социальной сети [1]. Опробовав несколько разных систем, группа разработки выбрала Hadoop для хранения и обработки информации, так как эта технология была экономичной и удовлетворяла их потребности в масштабировании.
Система Hive создавалась для того, чтобы аналитики, хорошо владеющие SQL (но слабо разбирающиеся в программировании на Java), могли выполнять запросы к гигантским объемам данных, хранимых Facebook в HDFS. Сегодня Hive — успешный проект Apache, используемый во многих организациях как универсальная и масштабируемая платформа обработки данных.
Взаимодействие с Hive в основном происходит через программную оболочку, в которой вводятся команды на HiveQL — языке запросов Hive, диалекте SQL. Хотя Hive во многих отношениях напоминает традиционные базы данных, из тесной связи этой технологии с HDFS и MapReduce вытекает целый ряд архитектурных различий, которые напрямую влияют на функциональность Hive — которая, в свою очередь, влияет на возможное применение Hive.
В традиционных базах данных схема таблицы проверяется во время загрузки данных. Если загружаемые данные не соответствуют схеме, они отвергаются. Такой метод называется проверкой схемы при записи. С другой стороны, Hive проверяет данные не при загрузке, а при выдаче запроса. Это называется проверкой схемы при чтении.
У каждого из двух методов есть свои достоинства и недостатки. Проверка схемы при чтении заметно ускоряет начальную загрузку, поскольку данные не нужно читать, разбирать и сериализовать на диск во внутреннем формате базы данных. Операция загрузки сводится к копированию или перемещению файла. Кроме того, улучшается гибкость обработки данных: возможно использовать две схемы для одного набора данных в зависимости от выполняемого анализа.
Проверка схемы при записи ускоряет выполнение запросов, потому что база данных может проиндексировать столбцы и выполнить сжатие данных. Вместе с тем процедура загрузки данных в базу выполняется медленнее. Кроме того, схема часто неизвестна на стадии загрузки. В таком случае индексирование невозможно, потому что запросы еще не были сформулированы. В таких ситуациях достоинства Hive проявляются особенно ярко.
По аналогии с Hive, Pig была придумана для работы с базами данных в целях экономии времени для разработчиков.
Создание приложений для MapReduce — дело достаточно трудоемкое. Написание всех функций, компилирование и упаковка занимают много времени. Чтобы облегчить работу компания Yahoo! разработала специализированный инструмент под названием Pig, повышающий уровень абстракции при обработке данных. Подробнее про Pig читайте в просторах Интернета, например тут:
- https://habr.com/ru/company/selectel/blog/215307/ — статья на Хабре от пользователя fortyseven 2014-го года;
- методичку преподавателя А.С. Лебедева (см. папку "docs" этого репозитория);
- или Википедию (к примеру тут, на английском: https://en.wikipedia.org/wiki/Apache_Pig).
Про эти вещи, дорогой читатель, почитайте сами — я уже подустал печатать про это :)
Это тема остальных двух лабораторных работ, которые я не выполнил по обсуждаемому нами здесь предмету "Методы BigData".
Вот некоторые из предлагаемых преподавателем источников:
- https://en.wikipedia.org/wiki/HITS_algorithm;
- http://pi.math.cornell.edu/~mec/Winter2009/RalucaRemus/Lecture4/lecture4.html;
- а вот на русском языке в Википедии: https://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_HITS.
Поскольку этот репозиторий содержит файлы Java-проекта от второй лабораторной работы на тему "Разработки двух алгоритмов MapReduce", то дальше будут выкладки в основном по этой работе.
Научиться реализовывать алгоритмы MapReduce на одном из языков программирования для понимания принципов работы этой технологии и, следовательно, всей системы Hadoop.
Необходимо решить задачу формирования списка рекомендованных товаров для пользователя интернет-магазина с применением алгоритма кросскорреляции (имея множество кортежей объектов, для каждой возможной пары объектов посчитать число кортежей, где они встречаются вместе).
- Реализовать два алгоритма на MapReduce:
- Cross Correlation Pairs
- Cross Correlation Stripes
- Написать генератор базы данных интернет-заказов (или взять готовую). Учесть, что заказ состоит из произвольного количества позиций (товаров).
- Обработать алгоритмом кросс-корреляции базу данных заказов (подсчитать количество вхождений каждой пары товаров).
- Реализовать компонент советника, не применяя паттерн MapReduce. Вводится название товара. Выводятся 10 товаров, которые чаще всего покупают с заданным товаром. Чтение результатов работы алгоритма кросс-корреляции из HDFS реализовать вручную (для Java — c помощью FileSystem API, для Python — с помощью библиотеки pyhdfs).
Как видно, я писал этот код на Java. Поэтому для его работы на вашем компьютере вам необходима Java-библиотека org.apache.hadoop (чтобы установить эти библиотеки, создайте проект в какой-нибудь IDE, к примеру IntelliJ IDEA, с автоустановщиком Java-библиотек "maven"; или просто добавьте к вам в проект jar-файл, который вы можете скачать, например, отсюда: https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-common/3.3.1).
В коде есть четыре файла:
CrossCorelation.java
: с реализацией первого алгоритма "Cross Correlation Pairs" (то есть реализация MapReduce в виде работы с парами: у меня в работе это пара двух объектов классаText
иIntWritable
);CrossCorelation2.java
: это файл с исходным кодом уже второго алгоритма "Cross Correlation Stripes" — в нём нужно уже реализовывать с передачей между map и reduce объектов кастомного класса (мой такой класс находится в файлеDict.java
);Dict.java
: файл с классомDict
, который представляет собой реализацию ассоциативного массива (HashMap
) для его передачи между частями MapReduce;Main.java
: это главный классMain
с настройкой и запуском этих двух алгоритмов MapReduce.
Следует вам немного объяснить содержние кода. Вообще справочник по программированию MapReduce на Java есть на официальном сайте https://hadoop.apache.org/docs/current/api/index.html. Здесь есть описание всех методов и классов предоставляемого программисту API.
В Java для работы с Hadoop MapReduce предусмотрены специальные классы, созданные поверх основных, нативных (от англ. "native") классов Java, но пригодных для хранения и обработки уже непосредственно в Hadoop. Это классы например IntWritable
, который хранит в себе обычное целое число, но пригодное для чтения и записи в систему HDFS; класс Text
, который представляет собой обычную строку, но с возможностью сохранить её в HDFS.
"Обернуть" обычную Java-строку класса String
в объект Text
можно таким способом:
String str = "Текст в Хадупе!"
Text hdfs_str = new Text(str);
То есть String
просто засовывается в конструктор класса Text
.
Функции Map и Reduce реализуются в Java в виде классов с соответствующими методами. У меня в проекте это классы MyMapper
и MyReducer
:
Код 1 — Общий вид алгоритма MapReduce в Java |
И обратите внимание, что в параметризуемых типах данных в классе Map последние два стоят такие: Text
и IntWritable
, — это значит, что и в классе Reduce первые два типа данных должны быть помечены как Text
и IntWritable
(см. код 1 выше). В точно таком же порядке следования. Это всё из-за того, что в терминологии MapReduce map — это входная функция этого алгоритма, которая после завершения своей работы передаёт частично обработанные данные функции reduce. И эти данные не изменяются в процессе передачи от map к reduce — следовательно, выходные типы данных класса Map в Java (и в любом другом языке программирования, работающим с MapReduce) должны совпадать с входными типами класса Reduce!
Иначе в процессе компиляции у вас выскочит ошибка, связанная с этим! Надеюсь, что в процессе компиляции, а не в процессе уже выполнения кода — я просто не помню :) В общем будьте с этим внимательны!
В официальной документации (см. https://hadoop.apache.org/docs/current/hadoop-mapreduce-client/hadoop-mapreduce-client-core/MapReduceTutorial.html#MapReduce_-_User_Interfaces) сказано следующее насчёт этих входов и выходов функций MapReduce:
Maps are the individual tasks that transform input records into intermediate records. The transformed intermediate records do not need to be of the same type as the input records. A given input pair may map to zero or many output pairs. |
Переводя на русский язык, здесь разработчикам, применяющим MapReduce у себя в проекте, то есть всем нам интересующимся, сообщают, что выходные типы данных класса Map (то есть последние два параметризуемых типа в коде 1 в классе MyMapper
) могут отличаться от его входных типов данных (то есть от первых двух типов в коде 1 в том же классе). Так и есть — код 1 успешно отрабатывает свою задачу несмотря на это различие типов.
Кроме этого, выходных типов данных вообще может не быть или их может быть намного больше. А последним предложением специалистам напоминают, что кол-во потоков, выделенных для фазы Map, напрямую зависит от количества обрабатываемых блоков памяти, в которых хранятся входные файлы. Этих блоков памяти может быть столько же сколько и самих входных файлов: здесь всё зависит от объёма этих входных файлов — занимают ли они один блок или несколько. То есть кол-во потоков, выполняющих функцию map, может варьироваться в разных ситуациях.
И здесь можно рассказать и о том, что в HDFS (см. если подзабыл, что это такое, введение) данные хранятся в виде отдельных фиксированных блоков, которые поточным образом обрабатываются сразу на разных машинах. Причём один и тот же файл или каталог могут располагаться одновременно по частям на разных компьютерах, которые встроены в обрабатывающую систему Hadoop. Эти компьютеры, кстати говоря, ещё называют узлами.
Обрабатывающих потоков Reduce тоже может быть несколько. При этом их число может отличаться от числа map-потоков, и разработчик может самостоятельно указать их количество посредством метода Job.setNumReduceTasks(int)
:
Reducer reduces a set of intermediate values which share a key to a smaller set of values. |
Также, если продолжать разговор о коде в этом репозитории, нужно упомянуть принципиальное отличие двух версий библиотек hadoop друг от друга и их несочетаемость в коде: это библиотека org.apache.hadoop.mapreduce
и более старая — org.apache.hadoop.mapred
! Если вы, читатель, импортируете их в свой код прямо вместе, то он так или иначе не заработает! Помните об этом — это две разные библиотеки, которые не предназначены для совместной работы. Как видите в коде этого репозитория, используется только библиотека org.apache.hadoop.mapreduce
(читайте об этом также на stackoverflow: https://stackoverflow.com/questions/16269922/hadoop-mapred-vs-hadoop-mapreduce).
Это всё, что хотелось бы рассказать о программировании MapReduce в рамках этой статьи. Желаю Вам, дорогой интересующийся этой темой читатель, интересного времяпрепровождения и отличного настроения!
- Лебедев А.С. Методы Big Data [Электронный ресурс]: Учебно-методическое пособие / Лебедев А.С., Магомедов Ш.Г. – М.: МИРЭА – Российский технологический университет, 2021. – 1 электрон. опт. диск (CD-ROM).
- Apache Pig // Wikipedia URL: https://en.wikipedia.org/wiki/Apache_Pig (дата обращения: 28.01.2022).
- Lecture #4: HITS Algorithm - Hubs and Authorities on the Internet // The Department of Mathematics URL: http://pi.math.cornell.edu/~mec/Winter2009/RalucaRemus/Lecture4/lecture4.html (дата обращения: 28.01.2022).
- Hadoop, часть 3: Pig, обработка данных // Хабр URL: https://habr.com/ru/company/selectel/blog/215307/ (дата обращения: 28.01.2022).
- MapReduce Tutorial // APACHE hadoop URL: https://hadoop.apache.org/docs/current/hadoop-mapreduce-client/hadoop-mapreduce-client-core/MapReduceTutorial.html (дата обращения: 28.01.2022).
- hadoop.mapred vs hadoop.mapreduce? // stackoverflow URL: https://stackoverflow.com/questions/16269922/hadoop-mapred-vs-hadoop-mapreduce (дата обращения: 28.01.2022).
Про остальные две лабораторные работы: первую и третью, — смотрите в приложенных к репозиторию документах в папке "docs"! Там лежат отчёты по ним, предназначенные для показа преподавателю как результатов работы по "Методам BigData".
И замечу ещё одну важную вещь — в методичке моего преподавателя А.С. Лебедева [1] также описан точный порядок установки Hadoop, Hive, Pig и других подобных инструментов в ОС Linux (в рамках нашего курса мы работали в CentOS 7). Она находится в этом репозитории в том же каталоге "docs".
А запускается требуемый в задании к этой работе клиент, рекомендующий товары покупателям, через bash-скрипт, который лежит в папке "target" и называется "client.sh". Дополняя к этому ещё пару поясняющих слов, можно сказать, что у оболочки bash после установки Хадупа появляется возможность вызывать команду
hdfs dfs <параметры>
, которая предназначена для работы с файловой системой HDFS: например, выполнение командыhdfs dfs -ls /user/user1
при запущенной системе Hadoop выведет все каталоги внутри HDFS-каталога /user/user1. В этом скрипте,
client.sh
, эта команда и применяется.Научиться же остальному в программировании на языке bash можно посетив один из туториалов в Интернете, к примеру этот: https://habr.com/ru/company/ruvds/blog/325522/ — статья от ru_vds 2017-го года. В этой статье есть полезная инфомация как для новичков, так и для ультрапрокаченных проггеров :) Оригинал этой статьи, кстати, тут: https://likegeeks.com/bash-script-easy-guide/.
Мой опыт установки Hadoop см. в документе MS Word "docs/Установка Hadoop.docx".
См. также теорию про Hadoop на ГитХабе от одного хорошего чувака, на которого я случайно наткнулся в поисковике: https://github.com/Kalter-M.
И да, второй алгоритм из задания (с ассоциативными массивами) работает, но не точно — его необходимо подкорректировать для более точных результатов!