Принципиально есть два типа инкрементального обновления: пакетный и потоковый.
Пакетный (batch) – данные загружаются большими блоками. Например, таблица с заказами клиентов обновляется раз в сутки в первый час ночи – происходит загрузка данных за последние сутки, и они добавляются в хранилище. Вариантов реализаций таких обновлений много – от специализированного софта до самописных систем. Я использовал оба подхода. В Ozon.ru и Wikimart.ru пользовался Microsoft Integration Services, которые входили в пакет MS SQL Server. В ней просто мышкой рисуются потоки данных между источником и хранилищем, программирования там минимум. В Retail Rocket использовалась самописная утилита без графического интерфейса, которая занималась скачиванием данных из Hadoop в ClickHouse.
Потоковый (stream) – данные загружаются по одной записи или мелкими пакетами по мере их поступления. Обычно это создается для данных, которые нужно поддерживать в «реальном времени». Если обратиться к примеру выше, то в таблицу с заказами клиентов новые заказы будут попадать по мере их появления. В таком случае будет небольшое запаздывание между созданием самого заказа и его появлением в хранилище. Оно может варьироваться от миллисекунд до часов, и это время обязательно контролируется через мониторинг.
Hadoop и MapReduce
Сначала расскажу, как появился Hadoop. К этому приложил руку Google. На мой взгляд, у этой компании есть два великих изобретения: PageRank и MapReduce. Джеффри Дин и Санджай Гемават (Jeffrey Dean и Sanjay Ghemawat) в течение четырех месяцев 2003 года разрабатывали технологию MapReduce [38]. Эта идея пришла к ним, когда они в третий раз переписывали движок Google, отвечающий за скачивание и индексацию страниц. Эти два разработчика решили важную проблему: они нашли способ скоординировать работу огромного числа зачастую ненадежных компьютеров в разных дата-центрах по всему миру. Ведь отказ одного или нескольких компьютеров потребует повторного запуска расчетов, что очень проблематично, когда мы имеем дело с тысячей машин. Но самое замечательное, что Дин и Гемават не просто нашли решение частной проблемы – они создали философию. MapReduce позволил разработчикам Google обращаться к серверам их дата-центров как к одному огромному компьютеру.
До изобретения MapReduce любой разработчик должен был придумывать схему, как разделить и распределить данные, запускать расчет и самостоятельно разбираться с отказом оборудования. MapReduce предложил новый принцип решения задач. Алгоритм требовал разбивать задачу на два этапа. Этап «Map» (предварительная обработка) – программист сообщает каждой машине, какую предобработку данных выполнить, например, посчитать, сколько раз слово «котик» встретилось на веб-странице. Затем нужно написать инструкции для этапа «Reduce» (свертка), например, заставить машины вычислить суммарное количество «котиков» на всех веб-страницах мира.
В 2004 году индексирующий движок Google был переведен на MapReduce. Затем эту технологию стали использовать для обработки видео и рендеринга карт Google Maps. Она была настолько проста, что ее стали использовать для широкого круга проблем. В том же году со стороны Google был заявлен патент [36] на MapReduce. Тогда же Джеффри и Санджай подумали, что было бы полезно познакомить астрономов, генетиков и других ученых, у которых очень много данных, c MapReduce. Они написали и опубликовали статью: «MapReduce: упрощенная обработка данных на больших кластерах» [37].
Статья произвела эффект разорвавшейся бомбы. Дешевое железо, рост числа веб-сервисов и подключенных устройств к Сети привели к «потопу» данных. На рынке было только несколько компаний с программными технологиями, которые могли справиться с этим. Дуг Каттинг и Майк Кафарелла (Mike Cafarella and Doug Cutting) работали над масштабированием своего поискового движка Nutch. Они были так впечатлены статьей, что на ее основе с нуля написали проект Hadoop. Затем Yahoo приглашает Каттинга продолжать работу над проектом внутри компании. В 2008 году начинается широкое применение Hadoop технологическими компаниями. Apache Hadoop сейчас распространяется под свободной лицензией [39].
Hadoop используется в большинстве технологических компаний, работающих с большими данными. Если не дистрибутив Apache, то какой-нибудь коммерческий от Mapr, Cloudera или другого вендора. Некоторые пошли своим путем и сделали собственную реализацию, например Яндекс.
Понять, как работает MapReduce, поможет иллюстрация (рис. 6.3).
Рис. 6.3. Подсчет числа слов в тексте
Слева у нас есть исходный текст, в каждой строке которого встречаются имена людей. Первая операция, Split, разрезает текст по строкам, каждая строка обрабатывается независимо от других. Вторая операция, Map, считает количество упоминаний каждого имени в строке. Ее мы можем проводить параллельно на разных машинах, так как строки независимы друг от друга. Третья операция, Shuffle, раскидывает одинаковые имена в группы. Четвертая операция, Reduce, считает сумму упоминаний каждого имени в разных строках. На выходе мы получаем число упоминаний каждого имени в тексте. Этот пример написан на трех строках, но с триллионом строк все операции были бы такими же.
MapReduce – это концепция. Hadoop – это программное обеспечение, которое реализует эту концепцию. Сам Hadoop состоит из двух главных компонент: распределенной файловой системы HDFS и планировщика ресурсов Yarn.
Файловая система HDFS (Hadoop Distributed File System) для пользователя выглядит как обычная файловая система с папками и файлами, которую вы привыкли видеть в своих компьютерах. Сама система располагается как минимум на одном компьютере. В ней есть две главные роли – name node (центральный узел имен) и data node (узел данных). Когда пользователь хочет записать файл в HDFS, происходит разбиение файла на блоки (размер блока зависит от настройки системы), name node возвращает data node, в который нужно сохранить блок. Клиент отправляет данные на data node, после записи данные реплицируются – копируются на другие ноды. По умолчанию коэффициент репликации составляет 3, то есть один блок данных будет на трех узлах данных. Как только процесс завершится и все блоки будут записаны, name node сделает соответствующую запись в своих таблицах (где какой блок хранится и к какому файлу относится). Это дает защиту от ошибок, например, когда сервер выходит из строя. С коэффициентом репликации 3 мы можем безболезненно потерять две ноды. Кстати, в таком случае HDFS самостоятельно обнаружит такие ноды и начнет реплицировать данные между «живыми» нодами, чтобы снова достичь нужного уровня репликации. Так мы достигаем устойчивости расчетов с точки зрения данных.
Планировщик ресурсов YARN отвечает за распределение вычислительных ресурсов на кластере Hadoop. Благодаря ему мы можем запускать на одном кластере несколько задач параллельно. Сами вычисления происходят, как правило, там же, где находятся данные, на тех же самых нодах с данными. Это экономит много времени, так как скорость чтения данных с диска гораздо выше, чем скорость копирования их по сети. При запуске задачи через Yarn ему явно нужно указать, сколько ресурсов для расчета вам нужно: сколько машин (executors) из кластера, сколько ядер процессора (cores) на каждой машине и сколько памяти. Сам Yarn также предоставляет отчет в реальном времени о выполнении задачи.