Школа
системного анализа
и проектирования
ДЖО РИС | МЭТТ ХОУСЛИ

Книга «Основы инженерии данных» (Fundamentals of Data Engineering)
Планирование и построение надёжных систем данных

2022 / 2024


Оглавление книги
Глава 7

Поглощение

Вы уже узнали о различных источниках данных, с которыми, вероятно, столкнётесь как инженер данных, и о способах хранения данных. Теперь давайте обратим внимание на шаблоны и решения, применяемые при поглощении данных из различных источников. В этой главе мы обсудим поглощение данных (см. рисунок 7-1), ключевые инженерные аспекты этого этапа, основные схемы пакетного и потокового поглощения, технологии, с которыми вы столкнётесь, с кем будете работать при разработке вашего конвейера поглощения данных, и как фоновые процессы проявляются на этапе поглощения.
Рисунок 7-1. Чтобы начать обработку данных, необходимо выполнить их поглощение

Что такое поглощение данных?

Поглощение данных — это процесс перемещения данных из одного места в другое. Поглощение данных подразумевает перемещение данных из исходных систем в хранилище в жизненном цикле инженерии данных, где поглощение является промежуточным этапом (рисунок 7-2).
Рисунок 7-2. Данные из системы 1 поступают в систему 2
Стоит кратко сравнить поглощение данных с интеграцией данных. В то время как поглощение данных — это перемещение данных из точки А в точку Б, интеграция данных объединяет данные из различных источников в новый набор данных. Например, вы можете использовать интеграцию данных, чтобы объединить данные из системы управления взаимоотношениями с клиентами (CRM), аналитические данные рекламы и веб-аналитику для создания профиля пользователя, который сохраняется в вашем хранилище данных. Кроме того, с помощью обратного ETL вы можете отправить этот новый профиль пользователя обратно в вашу CRM, чтобы сотрудники отдела продаж могли использовать данные для приоритизации лидов. Мы более подробно описываем интеграцию данных в главе 8, где обсуждаем трансформации данных; обратный ETL рассматривается в главе 9.

Также отметим, что поглощение данных отличается от внутреннего поглощения внутри системы. Данные, хранящиеся в базе данных, копируются из одной таблицы в другую, или данные в потоке временно кэшируются. Мы рассматриваем это как часть общего процесса трансформации данных, описанного в главе 8.
Определение конвейеров данных

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

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

В общем, вот наше определение конвейера данных:
Конвейер данных — это сочетание архитектуры, систем и процессов, которые перемещают данные через этапы жизненного цикла инженерии данных.

Наше определение намеренно гибкое и немного расплывчатое, чтобы позволить инженерам данных подключать всё, что им нужно для выполнения задачи. Конвейер данных может быть традиционной системой ETL, где данные поглощаются из локальной транзакционной системы, проходят через монолитный процессор и записываются в хранилище данных. Или это может быть облачный конвейер данных, который извлекает данные из 100 источников, объединяет их в 20 широких таблиц, обучает пять других моделей машинного обучения, развёртывает их в производство и отслеживает их постоянную производительность. Конвейер данных должен быть достаточно гибким, чтобы соответствовать любым потребностям на протяжении жизненного цикла инженерии данных.

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

Ключевые инженерные аспекты этапа поглощения

Вот несколько основных аспектов и вопросов, которые следует задать себе при подготовке к проектированию или созданию системы поглощения данных:
■ Какой кейс использования для данных, которые я поглощаю?
■ Могу ли я повторно использовать эти данные и избежать поглощения нескольких версий одного и того же набора данных?
■ Куда направляются данные? Какой у них пункт назначения?
■ Как часто данные должны обновляться из источника?
■ Какой ожидаемый объём данных?
■ В каком формате находятся данные? Могут ли нижестоящие системы хранения и трансформации принять этот формат?
■ Находятся ли исходные данные в хорошем состоянии для немедленного использования ниже по цепочке? То есть, каково качество данных? Какая пост-обработка требуется для их использования? Какие риски качества данных существуют (например, может ли трафик ботов на сайте загрязнить данные)?
■ Требуется ли обработка данных в процессе передачи для нижестоящего поглощения, если данные поступают из потокового источника?

Эти вопросы касаются как пакетного, так и потокового поглощения и применимы к базовой архитектуре, которую вы создадите, построите и будете поддерживать. Независимо от того, как часто данные поглощаются, вам следует учитывать следующие факторы при проектировании архитектуры поглощения:
■ Ограниченные (bounded) и неограниченные (unbounded) данные
■ Частота обновления данных
■ Синхронное и асинхронное поглощение
■ Сериализация и десериализация
■ Пропускная способность и масштабируемость
■ Надёжность и устойчивость
■ Полезная нагрузка
■ Модели push, pull и poll

Давайте рассмотрим каждый из этих аспектов подробнее.

Ограниченные и неограниченные данные

Как вы, возможно, помните из главы 3, данные бывают двух видов: ограниченные и неограниченные (рисунок 7-3). Неограниченные данные — это данные, существующие в реальности, по мере того как события происходят, либо спорадически, либо непрерывно, постоянно и потоково. Ограниченные данные — это удобный способ группировки данных по какому-либо признаку, например, по времени.
Рисунок 7-3. Ограниченные против неограниченных данных
Давайте примем следующий принцип: все данные являются неограниченными, пока их не ограничили. Как и многие принципы, этот не всегда точен на 100%. Например, список покупок, который я набросал днём, — это ограниченные данные. Я записал его как поток сознания (неограниченные данные) на клочок бумаги, где мысли теперь существуют как список вещей (ограниченные данные), которые мне нужно купить в магазине. Однако, этот принцип верен для большинства данных, с которыми вы будете иметь дело в бизнес-контексте.

Например, интернет-магазин будет обрабатывать транзакции клиентов 24 часа в сутки, пока бизнес не прекратит свою деятельность, экономика не остановится или солнце не взорвётся.

Бизнес-процессы давно накладывают искусственные ограничения на данные, разделяя их на дискретные пакеты. Помните о подлинной неограниченности ваших данных; потоковые системы поглощения данных — это просто инструмент для сохранения неограниченной природы данных, чтобы последующие этапы жизненного цикла могли также обрабатывать их непрерывно.

Частота поглощения

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

Частота поглощения данных может сильно варьироваться от медленной до быстрой (рисунок 7-4). На медленном конце спектра компания может отправлять свои налоговые данные в бухгалтерскую фирму один раз в год. На более быстром конце спектра система CDC (Change Data Capture) может получать новые обновления журнала из исходной базы данных каждую минуту. Ещё быстрее, система может непрерывно поглощать события от датчиков IoT и обрабатывать их в течение нескольких секунд. Частоты поглощения данных часто смешиваются в компании в зависимости от кейса использования и технологий.
Рисунок 7-4. Спектр частот поглощения данных: от пакетного до реального времени
Отметим, что шаблоны поглощения данных в «реальном времени» становятся всё более распространёнными. Мы берём «реальное время» в кавычки, потому что ни одна система поглощения не является по-настоящему реальной. Любая база данных, очередь или конвейер имеет встроенную задержку при доставке данных в целевую систему. Точнее было бы говорить о «почти реальном времени», но часто используют «реальное время» для краткости. Шаблон почти реального времени обычно исключает явную частоту обновлений; события обрабатываются в конвейере либо по одному, как они приходят, либо в микро-пакетах (то есть, пакетах за короткие временные интервалы). В этой книге мы будем использовать термины «реальное время» и «потоковое» как взаимозаменяемые.

Даже при наличии потокового процесса поглощения данных, пакетная обработка ниже по цепочке является относительно стандартной. На момент написания этой книги модели машинного обучения обычно обучаются на основе пакетных данных, хотя непрерывное онлайн-обучение становится всё более распространённым. Редко у инженеров данных есть возможность построить чисто почти реальный конвейер без пакетных компонентов. Вместо этого они выбирают, где будут происходить пакетные границы, то есть, на какие пакеты будут разбиваться данные в жизненном цикле инженерии данных. Как только данные достигают пакетного процесса, частота пакетов становится узким местом для всей последующей обработки.

Кроме того, потоковые системы наилучшим образом подходят для многих типов источников данных. В приложениях IoT типичный шаблон — это запись событий или измерений от каждого датчика в потоковые системы по мере их поступления. Хотя эти данные могут быть записаны непосредственно в базу данных, потоковая платформа поглощения, такая как Amazon Kinesis или Apache Kafka, лучше подходит для такого применения. Программные приложения могут использовать аналогичные шаблоны, записывая события в очередь сообщений по мере их поступления, а не дожидаясь процесса извлечения, который будет вытягивать события и информацию о состоянии из базы данных. Этот шаблон особенно хорошо работает для архитектур, управляемых событиями, которые уже обмениваются сообщениями через очереди. И снова, потоковые архитектуры обычно сосуществуют с пакетной обработкой.

Синхронное или асинхронное поглощение

При синхронном поглощении источник, процесс поглощения и пункт назначения имеют сложные зависимости и тесно связаны друг с другом. Как видно на рисунке 7-5, каждый этап жизненного цикла инженерии данных имеет процессы A, B и C, которые напрямую зависят друг от друга. Если процесс A терпит неудачу, процессы B и C не могут начаться; если процесс B терпит неудачу, процесс C не начинается. Этот тип синхронного рабочего процесса характерен для старых систем ETL, где данные, извлечённые из исходной системы, должны быть преобразованы перед загрузкой в хранилище данных. Процессы, следующие за поглощением, не могут начаться, пока все данные в пакете не будут поглощены. Если процесс поглощения или преобразования терпит неудачу, весь процесс должен быть перезапущен.
Рисунок 7-5. Синхронный процесс поглощения выполняется как дискретные пакетные этапы
Вот мини-кейс, иллюстрирующий, как не следует проектировать конвейеры данных. В одной компании процесс преобразования сам по себе состоял из серии десятков тесно связанных синхронных рабочих процессов, и весь процесс занимал более 24 часов. Если какой-либо этап этого конвейера преобразования терпел неудачу, весь процесс преобразования должен был быть перезапущен с самого начала! В этом случае мы видели, как процесс за процессом терпели неудачу, и из-за отсутствия или запутанных сообщений об ошибках, исправление конвейера превратилось в игру «ударь крота», которая заняла более недели для диагностики и устранения. В это время бизнес не получал обновлённые отчёты. Люди были недовольны.

При асинхронном поглощении зависимости могут теперь работать на уровне отдельных событий, как это происходит в программном обеспечении, построенном на микросервисах (рисунок 7-6). Отдельные события становятся доступными в хранилище сразу после их поглощения. Рассмотрим пример веб-приложения на AWS, которое отправляет события в Amazon Kinesis Data Streams (здесь выступающий в роли буфера). Поток считывается Apache Beam, который анализирует и обогащает события, а затем передаёт их во второй поток Kinesis; Kinesis Data Firehose объединяет события и записывает объекты в Amazon S3.
Рисунок 7-6. Асинхронная обработка потока событий в AWS
Основная идея заключается в том, что вместо полагания на асинхронную обработку, где пакетный процесс выполняется для каждого этапа по мере закрытия входного пакета и выполнения определённых временных условий, каждый этап асинхронного конвейера может обрабатывать элементы данных параллельно по мере их поступления в кластере Beam. Скорость обработки зависит от доступных ресурсов. Kinesis Data Streams выступает в роли амортизатора, сглаживая нагрузку так, чтобы всплески частоты событий не перегружали нижестоящую обработку. События будут быстро проходить через конвейер, когда частота событий низкая и любой задержки нет. Обратите внимание, что мы могли бы изменить сценарий и использовать Kinesis Data Streams для хранения, в конечном итоге извлекая события в S3 до их истечения из потока.

Сериализация и десериализация

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

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

Пропускная способность и масштабируемость

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

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

Ещё один момент, который следует учитывать, — это ваша способность обрабатывать всплески данных. Генерация данных редко происходит с постоянной скоростью и часто колеблется. Встроенное буферирование необходимо для сбора событий во время всплесков, чтобы данные не терялись. Буферизация позволяет выиграть время, пока система масштабируется, и позволяет системам хранения справляться с всплесками даже в динамически масштабируемой системе.

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

Надёжность и устойчивость

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

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

Наш совет — оценить риски и создать соответствующий уровень избыточности и самовосстановления на основе последствий и стоимости потери данных. Надёжность и устойчивость имеют как прямые, так и косвенные затраты. Например, продолжит ли ваш процесс поглощения работать, если выйдет из строя зона AWS? А как насчёт целого региона? А как насчёт энергосистемы или интернета? Конечно, ничего не бывает бесплатно. Сколько это будет стоить? Возможно, вы сможете построить высоко избыточную систему и иметь команду на дежурстве 24 часа в сутки для обработки сбоев. Но это также означает, что ваши облачные и трудовые затраты станут запредельными (прямые затраты), а постоянная работа будет сильно нагружать вашу команду (косвенные затраты). Нет единственно правильного ответа, и вам нужно оценить затраты и выгоды ваших решений по надёжности и устойчивости.

Не предполагайте, что вы можете построить систему, которая будет надёжно и устойчиво поглощать данные в любом возможном сценарии. Даже почти безграничный бюджет федерального правительства США не может гарантировать этого. В многих экстремальных сценариях поглощение данных на самом деле не будет иметь значения.

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

Полезная нагрузка

Полезная нагрузка (payload) — это набор данных, который вы поглощаете, и он имеет характеристики, такие как тип, форма, размер, схема и типы данных, а также метаданные. Давайте рассмотрим некоторые из этих характеристик, чтобы понять, почему это важно.
Тип
Тип данных, с которыми вы работаете, напрямую влияет на то, как они обрабатываются на последующих этапах жизненного цикла инженерии данных. Тип включает в себя тип и формат. Данные имеют тип — табличные, изображения, видео, текст и т.д. Тип данных напрямую влияет на формат данных или способ их выражения в байтах, именах и расширениях файлов. Например, табличные данные могут быть в форматах CSV или Parquet, каждый из которых имеет разные шаблоны байтов для сериализации и десериализации. Другим типом данных является изображение, которое имеет формат JPG или PNG и является неструктурированным по своей природе.
Форма
Каждая полезная нагрузка имеет форму, которая описывает её размеры. Форма данных критически важна на всех этапах жизненного цикла инженерии данных. Например, размеры пикселей и RGB (красный, зелёный, синий) изображения необходимы для обучения моделей глубокого обучения. В другом примере, если вы пытаетесь импортировать CSV-файл в таблицу базы данных, и ваш CSV имеет больше столбцов, чем таблица базы данных, вы, вероятно, получите ошибку во время процесса импорта. Вот несколько примеров форм различных типов данных:

Табличные данные
Количество строк и столбцов в наборе данных, обычно выражается как M строк и N столбцов.

Полуструктурированные JSON
Пары ключ-значение и глубина вложенности с подэлементами.

Неструктурированный текст
Количество слов, символов или байтов в теле текста.

Изображения
Ширина, высота и глубина цвета RGB (например, 8 бит на пиксель).

Несжатый аудио
Количество каналов (например, два для стерео), глубина сэмплов (например, 16 бит на сэмпл), частота сэмплов (например, 48 кГц) и длина (например, 10,003 секунды).
Размер
Размер данных описывает количество байтов полезной нагрузки. Полезная нагрузка может варьироваться по размеру от одного байта до терабайтов и более. Чтобы уменьшить размер полезной нагрузки, её можно сжать в различные форматы, такие как ZIP и TAR (см. обсуждение сжатия в Приложении A).

Огромную полезную нагрузку также можно разбить на части, что эффективно уменьшает её размер до более мелких подсекций. При загрузке большого файла в облачное хранилище объектов или хранилище данных это является общей практикой, так как небольшие отдельные файлы легче передавать по сети (особенно если они сжаты). Мелкие разбитые файлы отправляются к месту назначения и затем собираются обратно после прибытия всех данных.
Схема и типы данных
Многие полезные нагрузки данных имеют схему, такую как табличные и полуструктурированные данные. Как уже упоминалось в этой книге, схема описывает поля и типы данных в этих полях. Другие данные, такие как неструктурированный текст, изображения и аудио, не будут иметь явной схемы или типов данных. Однако они могут сопровождаться техническими описаниями файлов о форме, формате данных и файла, кодировке, размере и т.д.

Хотя вы можете подключаться к базам данных различными способами (например, экспорт файлов, CDC, JDBC/ODBC), подключение само по себе простое. Основная инженерная задача — понимание базовой схемы. Приложения организуют данные по-разному, и инженерам необходимо хорошо знать организацию данных и соответствующие шаблоны обновлений, чтобы понять их. Проблема усугубляется популярностью объектно-реляционного отображения (ORM), которое автоматически генерирует схемы на основе структуры объектов в языках, таких как Java или Python. Естественные структуры в объектно-ориентированном языке часто сопоставляются с чем-то сложным в операционной базе данных. Инженерам данных может потребоваться ознакомиться с классовой структурой кода приложения.

Схема не только для баз данных. Как мы обсуждали, API также имеют свои сложности со схемами. Многие API вендоров имеют удобные методы отчётности, которые подготавливают данные для аналитики. В других случаях инженерам не так везёт. API является тонкой обёрткой вокруг базовых систем, требующей от инженеров понимания внутренних механизмов приложения для использования данных.

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

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

Обнаружение и обработка изменений схемы вверх и вниз по цепочке. Изменения схемы часто происходят в исходных системах и обычно находятся вне контроля инженеров данных. Примеры изменений схемы включают:
■ Добавление нового столбца
■ Изменение типа столбца
■ Создание новой таблицы
■ Переименование столбца

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

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

Реестры схем. В потоковых данных каждое сообщение имеет схему, и эти схемы могут эволюционировать между производителями и потребителями. Реестр схем — это хранилище метаданных, используемое для поддержания целостности схемы и типов данных в условиях постоянно изменяющихся схем. Реестры схем также могут отслеживать версии схем и их историю. Они описывают модель данных для сообщений, обеспечивая последовательную сериализацию и десериализацию между производителями и потребителями. Реестры схем используются в большинстве крупных инструментов для работы с данными и облачных сервисов.
Метаданные
Помимо очевидных характеристик, которые мы только что рассмотрели, полезная нагрузка часто содержит метаданные, о которых мы впервые говорили в главе 2. Метаданные — это данные о данных. Метаданные могут быть столь же важны, как и сами данные. Одним из значительных ограничений раннего подхода к озеру данных — или «болоту данных», которое могло превратиться в «суперфонд данных» — было полное отсутствие внимания к метаданным. Без подробного описания данных они могут быть малоценными. Мы уже обсуждали некоторые типы метаданных (например, схемы) и будем возвращаться к этой теме многократно в течение этой главы.

Модели Push, Pull и Poll

Мы упоминали модели push и pull, когда вводили жизненный цикл инженерии данных в главе 2. Стратегия push (рисунок 7-7) предполагает, что исходная система отправляет данные на целевую, тогда как стратегия pull (рисунок 7-8) предполагает, что целевая система считывает данные непосредственно из источника. Как мы упоминали в том обсуждении, границы между этими стратегиями размыты.
Рисунок 7-7. Отправка данных от источника к цели
Рисунок 7-8. Целевая система считывает данные из источника
Ещё одной моделью, связанной с pull, является polling (опрос) данных (рисунок 7-9). Опрос предполагает периодическую проверку источника данных на наличие изменений. Когда изменения обнаружены, целевая система считывает данные так же, как в обычной ситуации pull.
Рисунок 7-9. Опрос изменений в исходной системе

Особенности пакетного поглощения

Пакетное поглощение, которое предполагает обработку данных в больших объёмах, часто является удобным способом поглощения данных. Это означает, что данные поглощаются путём выборки подмножества данных из исходной системы, основанной либо на временном интервале, либо на объёме накопленных данных (рисунок 7-10).
Рисунок 7-10. Пакетное поглощение на основе временных интервалов
Пакетное поглощение на основе временных интервалов широко распространено в традиционных бизнес-ETL для хранилищ данных. Этот шаблон часто используется для обработки данных один раз в день, ночью в нерабочее время, чтобы обеспечить ежедневную отчётность, но могут использоваться и другие частоты.
Рисунок 7-11. Пакетное поглощение на основе объёма
Пакетное поглощение на основе объёма довольно распространено, когда данные перемещаются из потоковой системы в объектное хранилище; в конечном итоге, данные необходимо разбить на дискретные блоки для последующей обработки в озере данных. Некоторые системы поглощения на основе объёма могут разбивать данные на объекты по различным критериям, таким как объём в байтах общего числа событий.

Некоторые часто используемые шаблоны пакетного поглощения, которые мы обсудим в этом разделе, включают:
■ Снимок или дифференциальное извлечение.
■ Файловый экспорт и поглощение.
■ ETL или ELT.
■ Вставки, обновления и размер пакета.
■ Миграция данных.

Снимок или дифференциальное извлечение

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

Экспорт и поглощение на основе файлов

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

Файловое поглощение имеет несколько потенциальных преимуществ по сравнению с прямым подключением к базе данных. Часто нежелательно предоставлять прямой доступ к бэкенд-системам по соображениям безопасности. При файловом поглощении процессы экспорта выполняются на стороне источника данных, предоставляя инженерам исходной системы полный контроль над тем, какие данные экспортируются и как они предварительно обрабатываются. После завершения файлов их можно передать в целевую систему различными способами. Распространённые методы обмена файлами включают объектное хранилище, протокол безопасной передачи файлов (SFTP), электронный обмен данными (EDI) или безопасную копию (SCP).

ETL или ELT

В главе 3 были представлены ETL и ELT, оба из которых являются чрезвычайно распространёнными шаблонами поглощения, хранения и трансформации данных, с которыми вы столкнётесь в пакетных нагрузках. Вот краткие определения этапов извлечения и загрузки в ETL и ELT:

Извлечение
Это означает получение данных из исходной системы. Хотя извлечение, кажется, подразумевает pull-данных, оно также может быть основано на push. Извлечение также может требовать чтения метаданных и изменений схемы.

Загрузка
После извлечения данных их можно либо преобразовать (ETL) перед загрузкой в целевое хранилище, либо просто загрузить в хранилище для последующего преобразования. При загрузке данных следует учитывать тип системы, в которую они загружаются, схему данных и влияние на производительность.

Мы более подробно рассмотрим ETL и ELT в главе 8.

Вставки, обновления и размер пакетов

Системы, ориентированные на пакетную обработку, часто работают неэффективно, когда пользователи пытаются выполнить множество операций с небольшими пакетами данных вместо меньшего количества крупных операций. Например, если в транзакционной базе данных обычно вставляют по одной строке за раз, то для многих колоночных баз данных это плохая практика, так как это приводит к созданию множества небольших, неоптимальных файлов и вынуждает систему выполнять большое количество операций создания объектов. Ещё большей проблемой является выполнение множества мелких операций обновления на месте, поскольку это заставляет базу данных сканировать каждый существующий файл столбца для выполнения обновления.

Понимайте подходящие шаблоны обновления для базы данных или хранилища данных, с которыми вы работаете. Также учитывайте, что некоторые технологии специально разработаны для высокой скорости вставки. Например, Apache Druid и Apache Pinot могут справляться с высокой частотой вставок. SingleStore способен управлять гибридными нагрузками, сочетающими характеристики OLAP и OLTP. BigQuery плохо справляется с высокой частотой вставок одиночных строк через обычный SQL, но работает крайне эффективно, если данные поступают через его потоковый буфер. Знайте ограничения и особенности ваших инструментов.

Миграция данных

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

Миграция данных, вероятно, не будет регулярной задачей для инженера данных, но вы должны быть с ней знакомы. Как и в случае с загрузкой данных, управление схемами является ключевым аспектом. Предположим, вы переносите данные из одной системы базы данных в другую (например, из SQL Server в Snowflake). Независимо от того, насколько похожи эти базы данных, почти всегда существуют тонкие различия в том, как они обрабатывают схемы. К счастью, обычно легко протестировать загрузку образца данных и выявить проблемы со схемой перед выполнением полной миграции таблицы.

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

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

Особенности поглощения сообщений и потоков данных

Поглощение данных о событиях — это распространённая задача. В этом разделе рассматриваются вопросы, которые следует учитывать при поглощении информации о событиях, с опорой на темы, затронутые в Главах 5 и 6.

Эволюция схем

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

Вот несколько рекомендаций для смягчение проблем, связанныех с эволюцией схемы. Во-первых, если ваша платформа обработки событий имеет реестр схем (schema registry, обсуждался ранее в этой главе), используйте его для управления версиями изменений схемы. Во-вторых, очередь недоставленных сообщений (dead-letter queue, описана в разделе «Обработка ошибок и очереди недоставленных сообщений» на странице 249) может помочь исследовать проблемы с событиями, которые не были корректно обработаны. Наконец, самый простой и эффективный подход — это регулярное взаимодействие с заинтересованными сторонами, ответственными за источники данных, для обсуждения потенциальных изменений схемы и активного решения этих изменений на этапе их внедрения, а не реагирования на последствия.

Данные, поступающие с задержкой

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

Например, IoT-устройство может задержать отправку сообщения из-за проблем с интернет-задержками. Это часто встречается при приёме данных. Вы должны учитывать возможность появления поздно поступающих данных и их влияние на последующие системы и процессы. Если вы предполагаете, что время приёма или обработки совпадает с временем события, вы можете получить странные результаты, если ваши отчёты или анализ зависят от точного отображения времени событий. Чтобы справиться с поздно поступающими данными, необходимо установить временной порог, после которого такие данные больше не будут обрабатываться.

Порядок и многократная доставка

Потоковые платформы обычно строятся на основе распределённых систем, что может вызывать некоторые сложности. В частности, сообщения могут доставляться не по порядку и более одного раза (гарантия доставки «хотя бы один раз»). Подробнее об этом см. в обсуждении платформ потоковой обработки событий в Главе 5.

Воспроизведение

Воспроизведение (replay) позволяет читателям запрашивать диапазон сообщений из истории, что даёт возможность «перемотать» историю событий до определённого момента времени. Эта функция является ключевой возможностью многих платформ потокового приёма данных и особенно полезна, когда необходимо повторно загрузить и обработать данные за определённый временной диапазон. Например, RabbitMQ обычно удаляет сообщения после того, как все подписчики их обработают. Kafka, Kinesis и Pub/Sub поддерживают хранение событий и их повторное воспроизведение.

Время жизни

Как долго вы будете хранить записи о событиях? Ключевым параметром является максимальное время хранения сообщений, также известное как время жизни (TTL? Time to Live). TTL — это обычно настраиваемый параметр, определяющий, как долго события должны храниться до их подтверждения и приёма. Любое неподтверждённое событие, которое не было обработано после истечения его TTL, автоматически удаляется. Это помогает снизить нагрузку и уменьшить объём ненужных событий в вашем конвейере приёма данных.

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

Давайте рассмотрим, как некоторые популярные платформы обрабатывают TTL на момент написания этой книги. Google Cloud Pub/Sub поддерживает срок хранения до 7 дней. Amazon Kinesis Data Streams позволяет увеличить срок хранения до 365 дней. Kafka можно настроить на неограниченное хранение, ограниченное только доступным дисковым пространством. (Kafka также поддерживает возможность записи старых сообщений в облачное объектное хранилище, что позволяет практически неограниченно увеличивать объём хранения и сроки.)

Размер сообщений

Размер сообщений — это легко упускаемый из виду аспект: необходимо убедиться, что выбранная потоковая платформа может обрабатывать максимально ожидаемый размер сообщений. Amazon Kinesis поддерживает максимальный размер сообщения в 1 МБ. Kafka по умолчанию также использует этот размер, но может быть настроен на максимальный размер 20 МБ или больше. (Возможности настройки могут варьироваться в зависимости от управляемых сервисных платформ.)

Обработка ошибок и очереди недоставленных сообщений

Иногда события не удаётся успешно принять. Например, событие может быть отправлено в несуществующий топик или очередь, размер сообщения может быть слишком большим, или событие могло истечь по сроку TTL. События, которые не могут быть обработаны, необходимо перенаправлять и сохранять в отдельном месте, называемом очередью недоставленных сообщений (dead-letter queue).

Очередь недоставленных сообщений отделяет проблемные события от тех, которые могут быть приняты потребителем (Рисунок 7-12). Если события не перенаправляются в очередь недоставленных сообщений, эти ошибочные события рискуют блокировать обработку других сообщений. Инженеры данных могут использовать очередь недоставленных сообщений, чтобы диагностировать причины ошибок при обработке событий и решать проблемы в конвейере данных, а также, возможно, переработать некоторые сообщения в очереди после устранения основной причины ошибок.
Рисунок 7-12. «Хорошие» события передаются потребителю, тогда как «плохие» события хранятся в очереди недоставленных сообщений.

Pull и Push для потребителей

Потребитель, подписывающийся на тему, может получать события двумя способами: push и pull. Рассмотрим, как некоторые технологии потоковой передачи данных реализуют эти методы. Kafka и Kinesis поддерживают только подписки pull. Подписчики читают сообщения из темы и подтверждают их обработку. Помимо подписок pull, Pub/Sub и RabbitMQ поддерживают push-подписки, позволяя этим сервисам отправлять сообщения слушателю.

Подписки pull являются стандартным выбором для большинства приложений в области инженерии данных, но для специализированных приложений можно рассмотреть возможности push. Обратите внимание, что системы, поддерживающие только pull-подписки, могут реализовать push, если добавить дополнительный уровень для обработки этого.

Местоположение

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

Способы поглощения данных

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

Прямое подключение к базе данных

Данные могут быть извлечены из баз данных путём выполнения запросов и чтения через сетевое подключение. Чаще всего это подключение осуществляется с использованием ODBC или JDBC. ODBC использует драйвер, установленный на клиенте, для перевода команд, отправленных на стандартный API ODBC, в команды, отправляемые в базу данных. База данных возвращает результаты запросов по сети, где драйвер получает их и переводит обратно в стандартную форму для чтения клиентом. Для получения данных приложение, использующее драйвер ODBC, является инструментом получения данных. Инструмент получения данных может извлекать данные с помощью множества небольших запросов или одного большого запроса.

JDBC концептуально очень похож на ODBC. Драйвер Java подключается к удалённой базе данных и служит промежуточным слоем между стандартным API JDBC и собственным сетевым интерфейсом целевой базы данных. Может показаться странным наличие API базы данных, предназначенного для одного языка программирования, но для этого есть веские причины. Виртуальная машина Java (JVM) является стандартной, кроссплатформенной и обеспечивает производительность компилируемого кода через компилятор JIT. JVM — это чрезвычайно популярная виртуальная машина для выполнения кода в кроссплатформенном режиме.

JDBC обеспечивает невероятную переносимость драйверов баз данных. Драйверы ODBC поставляются в виде двоичных файлов для конкретных операционных систем и архитектур; поставщики баз данных должны поддерживать версии для каждой архитектуры/версии ОС, которые они хотят поддерживать. С другой стороны, поставщики могут предоставить единственный драйвер JDBC, совместимый с любым языком JVM (например, Java, Scala, Clojure или Kotlin) и фреймворком данных JVM (например, Spark). JDBC стал настолько популярным, что его также используют в качестве интерфейса для языков, не относящихся к JVM, таких как Python; экосистема Python предоставляет инструменты перевода, которые позволяют коду Python взаимодействовать с драйвером JDBC, работающим на локальной JVM.

ODBC и JDBC широко используются для получения данных из реляционных баз данных, возвращаясь к общей концепции прямого подключения к базе данных. Различные улучшения используются для ускорения получения данных. Многие фреймворки данных могут параллелить несколько одновременных подключений и разделять запросы для параллельного получения данных. Однако ничего не даётся даром; использование параллельных подключений также увеличивает нагрузку на исходную базу данных.
ODBC и JDBC долгое время были золотым стандартом для получения данных из баз данных, но эти стандарты подключения начинают устаревать для многих приложений в области инженерии данных. Эти стандарты подключения испытывают трудности с вложенными данными и отправляют данные в виде строк. Это означает, что собственные вложенные данные должны быть перекодированы в строковые данные для отправки по сети, а столбцы из столбцовых баз данных должны быть повторно сериализованы в строки.

Как обсуждалось в разделе «Экспорт и получение данных на основе файлов», многие базы данных теперь поддерживают собственный экспорт файлов, который обходит JDBC/ODBC и экспортирует данные непосредственно в форматах, таких как Parquet, ORC и Avro. Кроме того, многие облачные хранилища данных предоставляют прямые API REST.

Подключения JDBC обычно интегрируются с другими технологиями получения данных. Например, мы часто используем процесс чтения для подключения к базе данных с помощью JDBC, записываем извлечённые данные в несколько объектов, а затем организуем получение данных в нижестоящую систему (см. Рисунок 7-13). Процесс чтения может выполняться в полностью эфемерном облачном экземпляре или в системе оркестрации.
Рисунок 7-13. Процесс получения данных читает данные из исходной базы данных с использованием JDBC, а затем записывает объекты в объектное хранилище. Целевая база данных (не показана) может быть запущена для получения данных с помощью вызова API из системы оркестрации

Захват изменения данных

Захват изменения данных (CDC, Change data capture) — это процесс получения изменений из исходной базы данных. Например, у нас может быть исходная система PostgreSQL, поддерживающая приложение, и периодически или непрерывно получающая изменения таблиц для аналитики.

Обратите внимание, что наше обсуждение здесь не является исчерпывающим. Мы представляем вам общие шаблоны, но рекомендуем ознакомиться с документацией по конкретной базе данных для обработки деталей стратегий CDC
Пакетно-ориентированный CDC
Если таблица базы данных содержит поле updated_at с последним временем записи или обновления записи, мы можем выполнить запрос к таблице, чтобы найти все обновлённые строки с указанного времени. Мы устанавливаем фильтр времени на основе того, когда мы в последний раз захватывали изменённые строки из таблиц. Этот процесс позволяет нам извлекать изменения и дифференцированно обновлять целевую таблицу.

Эта форма пакетной CDC имеет ключевое ограничение: хотя мы можем легко определить, какие строки изменились с определённого момента времени, мы не обязательно получаем все изменения, применённые к этим строкам. Рассмотрим пример выполнения пакетной CDC на таблице банковских счетов каждые 24 часа. Эта операционная таблица показывает текущий баланс каждого счёта. Когда деньги перемещаются между счетами, банковское приложение выполняет транзакцию для обновления баланса.

Когда мы выполняем запрос для возврата всех строк в таблице счетов, которые изменились за последние 24 часа, мы увидим записи для каждого счёта, зарегистрировавшего транзакцию. Предположим, что определённый клиент снял деньги пять раз с помощью дебетовой карты за последние 24 часа. Наш запрос вернёт только последний баланс счёта, зарегистрированный в течение 24-часового периода; другие записи за этот период не появятся. Эту проблему можно смягчить, используя схему только для вставки, где каждая транзакция счёта регистрируется как новая запись в таблице (см. «Только вставка»).
Непрерывный CDC
Непрерывный CDC захватывает всю историю изменений таблицы и может поддерживать почти реальное время обработки данных, либо для репликации базы данных в реальном времени, либо для обеспечения аналитики потоковых данных в реальном времени. Вместо того чтобы запускать периодические запросы для получения пакета изменений таблицы, непрерывный CDC рассматривает каждую запись в базу данных как событие.

Мы можем захватывать поток событий для непрерывного CDC несколькими способами. Один из самых распространённых подходов с транзакционной базой данных, такой как PostgreSQL, — это CDC на основе журналов. Бинарный журнал базы данных последовательно записывает каждое изменение в базе данных (см. «Журналы базы данных»). Инструмент CDC может читать этот журнал и отправлять события на целевую платформу, такую как Apache Kafka Debezium.

Некоторые базы данных поддерживают упрощённую, управляемую парадигму CDC. Например, многие облачные базы данных можно настроить так, чтобы они непосредственно запускали серверную функцию или записывали в поток событий каждый раз, когда в базе данных происходит изменение. Это полностью освобождает инженеров от необходимости беспокоиться о том, как события захватываются в базе данных и передаются.
CDC и репликация базы данных
CDC можно использовать для репликации между базами данных: события буферизуются в поток и асинхронно записываются во вторую базу данных. Однако многие базы данных поддерживают тесно связанную версию репликации (синхронную репликацию), которая поддерживает реплику в полной синхронизации с основной базой данных. Синхронная репликация обычно требует, чтобы основная база данных и реплика были одного типа (например, PostgreSQL к PostgreSQL). Преимущество синхронной репликации заключается в том, что вторичная база данных может разгружать основную базу данных, выполняя роль реплики для чтения; запросы на чтение могут быть перенаправлены на реплику. Запрос вернёт те же результаты, что и основная база данных.

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

Преимущество асинхронной репликации CDC заключается в слабо связанной архитектуре. Хотя реплика может немного отставать от основной базы данных, это часто не является проблемой для аналитических приложений, и события теперь могут быть направлены на различные цели; мы можем выполнять репликацию CDC, одновременно направляя события в объектное хранилище и процессор аналитики потоковых данных.
Особенности CDC
Как и всё в технологиях, CDC не является бесплатным. CDC потребляет различные ресурсы базы данных, такие как память, пропускная способность диска, хранилище, процессорное время и пропускная способность сети. Инженеры должны работать с производственными командами и проводить тесты перед включением CDC на производственных системах, чтобы избежать операционных проблем. Подобные соображения применимы и к синхронной репликации.

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

API

Большая часть программной инженерии — это просто обслуживание конвейра.
— Карл Хьюз
Как мы упоминали в главе 5, API являются источником данных, который продолжает расти в значимости и популярности. Типичная организация может иметь сотни внешних источников данных, таких как SaaS-платформы или компании-партнёры. Суровая реальность заключается в том, что не существует надлежащего стандарта для обмена данными через API. Инженеры данных могут тратить значительное количество времени на чтение документации, общение с внешними владельцами данных, а также на написание и поддержку кода для подключения к API.

Три тенденции постепенно изменяют эту ситуацию. Во-первых, многие поставщики предоставляют библиотеки API-клиентов для различных языков программирования, что устраняет большую часть сложности доступа к API.
Во-вторых, существует множество платформ для подключения данных, доступных в виде SaaS, с открытым исходным кодом или управляемых с открытым исходным кодом. Эти платформы обеспечивают готовую связь с множеством источников данных; они предлагают фреймворки для написания пользовательских коннекторов для неподдерживаемых источников данных. См. «Управляемые коннекторы данных».

Третья тенденция — это появление обмена данными (рассматривалось в главе 5), то есть возможность обмена данными через стандартные платформы, такие как BigQuery, Snowflake, Redshift или S3. Как только данные попадают на одну из этих платформ, их легко хранить, обрабатывать или перемещать в другое место. Обмен данными оказал значительное и быстрое влияние на сферу инженерии данных.

Не изобретайте велосипед, когда обмен данными невозможен и необходим прямой доступ к API. Хотя управляемая служба может показаться дорогой, подумайте о ценности вашего времени и альтернативных издержках на разработку API-коннекторов, когда можно заниматься более ценной работой.
Кроме того, многие управляемые сервисы теперь поддерживают создание пользовательских API-коннекторов. Это может включать предоставление технических спецификаций API в стандартном формате или написание кода коннектора, который работает в бессерверной функциональной среде (например, AWS Lambda), позволяя управляемому сервису заниматься деталями планирования и синхронизации. Эти сервисы могут значительно сэкономить время инженеров как на разработку, так и на последующее сопровождение.

Оставьте работу над пользовательскими подключениями для API, которые недостаточно поддерживаются существующими фреймворками; вы обнаружите, что таких API ещё много. Обработка пользовательских подключений API включает два основных аспекта: разработка программного обеспечения и операции. Следуйте лучшим практикам разработки программного обеспечения; используйте систему контроля версий, непрерывную доставку и автоматизированное тестирование. Помимо следования лучшим практикам DevOps, рассмотрите возможность использования фреймворка оркестрации, который может значительно упростить операционную нагрузку при обработке данных.

Очереди сообщений и платформы потоковой передачи событий

Очереди сообщений и платформы потоковой передачи событий — это распространённые способы получения данных в реальном времени из веб- и мобильных приложений, датчиков IoT и умных устройств. Поскольку данные в реальном времени становятся всё более повсеместными, вам часто приходится внедрять или модернизировать способы обработки данных в реальном времени в ваших рабочих процессах. Поэтому важно знать, как получать данные в реальном времени. Популярные способы получения данных в реальном времени включают очереди сообщений или платформы потоковой передачи событий, которые мы рассматривали в главе 5. Хотя это и источники данных, они также служат способами получения данных. В обоих случаях вы потребляете события от издателя, на которого подписаны.

Вспомните различия между сообщениями и потоками. Сообщение обрабатывается на уровне отдельного события и предназначено для временного хранения. Как только сообщение потребляется, оно подтверждается и удаляется из очереди. С другой стороны, поток событий записывается в упорядоченный журнал. Журнал сохраняется столько, сколько необходимо, позволяя событиям запрашиваться в различных диапазонах, агрегироваться и объединяться с другими потоками для создания новых преобразований, публикуемых для потребителей ниже по цепочке. На рисунке 7-14 у нас есть два производителя (производитель 1 и производитель 2), отправляющие события двум потребителям (потребитель 1 и потребитель 2). Эти события объединяются в новый набор данных и отправляются издателю для последующего потребления.

Последний пункт — это важное различие между пакетной и потоковой обработкой данных. В то время как пакетная обработка обычно включает статические рабочие процессы (получение данных, их хранение, преобразование и предоставление), сообщения и потоки более гибкие. Получение данных может быть нелинейным, с данными, которые публикуются, потребляются, повторно публикуются и повторно потребляются. При разработке ваших рабочих процессов получения данных в реальном времени учитывайте, как будут перемещаться данные.
Рисунок 7-14. Два набора данных производятся и потребляются (producer 1 и producer 2), затем объединяются, и объединенные данные публикуются новым производителем (producer 3)
Ещё один аспект — это пропускная способность ваших потоковых конвейеров данных. Сообщения и события должны перемещаться с минимальной задержкой, что означает необходимость обеспечения достаточной пропускной способности и ширины полосы разделов (или сегментов). Обеспечьте достаточные ресурсы памяти, диска и процессора для обработки событий, и если вы управляете своими потоковыми конвейерами, включите автомасштабирование для обработки пиковых нагрузок и экономии средств при снижении нагрузки. По этим причинам управление вашей потоковой платформой может включать значительные накладные расходы. Рассмотрите возможность использования управляемых сервисов для ваших потоковых конвейеров данных и сосредоточьтесь на способах получения ценности из ваших данных в реальном времени.

Управляемые коннекторы данных

сли вы рассматриваете возможность написания коннектора для получения данных из базы данных или API, спросите себя: не создано ли это уже? Более того, существует ли сервис, который будет управлять всеми деталями этого подключения за вас? В разделе «API» на странице 254 упоминается популярность платформ и фреймворков управляемых коннекторов данных. Эти инструменты стремятся предоставить стандартный набор коннекторов, доступных из коробки, чтобы избавить инженеров данных от необходимости создавать сложные подключения к конкретному источнику. Вместо создания и управления коннектором данных вы передаёте эту услугу стороннему поставщику.

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

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

Перемещение данных с использованием объектного хранилища

Объектное хранилище — это многопользовательская система в публичных облаках, поддерживающая хранение огромных объёмов данных. Это делает объектное хранилище идеальным для перемещения данных в данных озёра, между командами и для передачи данных между организациями. Вы даже можете предоставить краткосрочный доступ к объекту с помощью подписанного URL, давая пользователю временное разрешение.

На наш взгляд, объектное хранилище — это наиболее оптимальный и безопасный способ обработки обмена файлами. Облачное хранилище реализует последние стандарты безопасности, имеет надёжную историю масштабируемости и надёжности, принимает файлы произвольных типов и размеров и обеспечивает высокопроизводительное перемещение данных. Мы более подробно обсуждали объектное хранилище в главе 6.

EDI

Ещё одна практическая реальность для инженеров данных — это электронный обмен данными (EDI - electronic data interchange). Этот термин достаточно расплывчат и может относиться к любому методу передачи данных. Обычно он подразумевает несколько устаревшие способы обмена файлами, такие как электронная почта или флеш-накопители. Инженеры данных часто сталкиваются с источниками данных, которые не поддерживают более современные методы передачи данных, часто из-за устаревших ИТ-систем или ограничений человеческих процессов.

Инженеры могут улучшить EDI с помощью автоматизации. Например, они могут настроить облачный почтовый сервер, который сохраняет файлы в корпоративное объектное хранилище сразу после их получения. Это может запускать процессы оркестрации для получения и обработки данных. Это гораздо надёжнее, чем когда сотрудник загружает вложенный файл и вручную загружает его во внутреннюю систему, что, к сожалению, всё ещё часто встречается.

Базы данных и экспорт файлов

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

Основные облачные хранилища данных, такие как Snowflake, BigQuery, Redshift и другие, высоко оптимизированы для прямого экспорта файлов. Например, они поддерживают прямой экспорт в объектное хранилище в различных форматах.

Практические вопросы, связанные с основными форматами файлов

Инженеры также должны учитывать форматы файлов для экспорта. CSV до сих пор повсеместно используется, но он очень подвержен ошибкам. Например, разделителем по умолчанию в CSV является запятая — один из самых распространённых символов в английском языке! Но это ещё не всё.

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

Более надёжные и выразительные форматы экспорта включают Parquet, Avro, Arrow и ORC или JSON. Эти форматы кодируют информацию о схеме и обрабатывают произвольные строковые данные без дополнительных вмешательств. Многие из них также поддерживают вложенные структуры данных, так что поля JSON хранятся с использованием внутренних вложенных структур, а не простых строк. Для столбцовых баз данных столбцовые форматы (Parquet, Arrow, ORC) позволяют более эффективно экспортировать данные, так как столбцы могут быть непосредственно транскодированы между форматами. Эти форматы также обычно лучше оптимизированы для движков запросов. Формат файла Arrow разработан для прямого отображения данных в память обработки, обеспечивая высокую производительность в средах озёр данных.

Недостаток этих новых форматов заключается в том, что многие из них не поддерживаются исходными системами напрямую. Инженерам данных часто приходится работать с данными в формате CSV и разрабатывать надёжную обработку исключений и обнаружение ошибок для обеспечения качества данных при получении. Более подробное обсуждение форматов файлов можно найти в Приложении A.

Оболочка

Оболочка (shell) — это интерфейс, с помощью которого можно выполнять команды для получения данных. Оболочка может использоваться для написания скриптов рабочих процессов практически для любого программного инструмента, и скрипты оболочки всё ещё широко используются в процессах получения данных. Скрипт оболочки может читать данные из базы данных, пересериализовывать их в другой формат файла, загружать в объектное хранилище и запускать процесс получения данных в целевой базе данных. Хотя хранение данных на одном экземпляре или сервере не является высокомасштабируемым, многие наши источники данных не особенно велики, и такие подходы работают нормально.

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

SSH

SSH — это не стратегия получения данных, а протокол, используемый в других стратегиях получения данных. Мы используем SSH несколькими способами. Во-первых, SSH можно использовать для передачи файлов с помощью SCP, как упоминалось ранее. Во-вторых, SSH-туннели позволяют создавать безопасные, изолированные соединения с базами данных.

Базы данных приложений никогда не должны быть напрямую доступны в интернете. Вместо этого инженеры могут настроить бастион-хост — промежуточный хост, который может подключаться к нужной базе данных. Этот хост доступен в интернете, но защищён для минимального доступа только с определённых IP-адресов и на определённые порты. Чтобы подключиться к базе данных, удалённая машина сначала открывает SSH-туннель к бастион-хосту, а затем подключается к базе данных с этого хоста.

SFTP и SCP

Доступ и отправка данных через защищённый FTP (SFTP) и защищённую копию (SCP) — это техники, с которыми вам следует быть знакомы, даже если инженеры данных не используют их регулярно (этим обычно занимаются IT или специалисты по безопасности).

Инженеры справедливо морщатся при упоминании SFTP (иногда даже встречаются случаи использования FTP в продакшене). Тем не менее, SFTP остаётся практической реальностью для многих бизнесов. Они работают с партнёрами, которые потребляют или предоставляют данные через SFTP и не желают полагаться на другие стандарты. Чтобы избежать утечек данных, в таких ситуациях критически важен анализ безопасности.

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

Веб-хуки

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

С вебхуками (рисунок 7-15) поставщик данных определяет спецификацию API-запроса, но сам отправляет API-вызовы, а не получает их; потребитель данных должен предоставить API-конечную точку для вызова поставщиком. Потребитель отвечает за получение каждого запроса и обработку агрегации, хранения и обработки данных.
Рисунок 7-15. Базовая архитектура поглощения при помощи веб-хуков, построенная на основе облачных сервисов
Архитектуры получения данных на основе веб-хуков могут быть хрупкими, сложными в сопровождении и неэффективными. Используя подходящие готовые инструменты, инженеры данных могут создавать более надёжные архитектуры вебхуков с меньшими затратами на сопровождение и инфраструктуру. Например, шаблон вебхуков в AWS может использовать бессерверный фреймворк (Lambda) для получения входящих событий, управляемую платформу потоковой передачи событий для хранения и буферизации сообщений (Kinesis), фреймворк обработки потоков для обработки аналитики в реальном времени (Flink) и объектное хранилище для долговременного хранения (S3).

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

Веб-интерфейсы

Веб-интерфейсы для доступа к данным остаются практической реальностью для инженеров данных. Часто встречаются ситуации, когда не все данные и функции SaaS-платформы доступны через автоматизированные интерфейсы, такие как API и файловые дропы. Вместо этого кто-то должен вручную получить доступ к веб-интерфейсу, сгенерировать отчёт и скачать файл на локальную машину. Это имеет очевидные недостатки, такие как забывчивость людей или проблемы с оборудованием. Где возможно, выбирайте инструменты и рабочие процессы, позволяющие автоматизировать доступ к данным.

Веб-скрейпинг

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

Вот несколько ключевых советов, которые следует учитывать перед началом любого проекта по веб-скрейпингу. Во-первых, спросите себя, действительно ли вам нужно заниматься веб-скрейпингом или данные доступны от стороннего поставщика. Если вы решили заниматься веб-скрейпингом, будьте ответственным пользователем. Не создавайте случайно атаку типа «отказ в обслуживании» (DoS) и не допускайте блокировки вашего IP-адреса. Понимайте, сколько трафика вы генерируете, и соответственно распределяйте активность веб-краулинга. Только потому, что вы можете запустить тысячи одновременных Lambda-функций для скрейпинга, не значит, что это нужно делать; чрезмерный веб-скрейпинг может привести к отключению вашего аккаунта AWS.

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

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

Веб-скрейпинг имеет интересные последствия для этапа обработки данных в жизненном цикле инженерии данных. Инженеры должны заранее продумать несколько факторов: что вы собираетесь делать с данными? Просто извлекать необходимые поля из HTML с помощью Python-кода и записывать эти значения в базу данных? Или планируете сохранять полный HTML-код веб-страниц и обрабатывать эти данные с помощью фреймворка, такого как Spark? Эти решения могут привести к совершенно разным архитектурам на этапе получения данных.

Устройства для передачи данных при миграции

Для огромных объёмов данных (100 ТБ и более) передача данных напрямую через интернет может быть медленным и дорогостоящим процессом. В таких масштабах самый быстрый и эффективный способ перемещения данных — это не по сети, а с помощью грузовика. Облачные провайдеры предлагают возможность отправить данные с помощью физического «ящика с жёсткими дисками». Просто закажите устройство хранения, называемое передаточным устройством, загрузите на него данные с ваших серверов, а затем отправьте его обратно провайдеру, который загрузит ваши данные.
Рекомендуется рассмотреть использование передаточного устройства, если объём ваших данных составляет около 100 ТБ. На другом конце спектра, AWS даже предлагает Snowmobile — передаточное устройство, доставляемое в полуприцепе! Snowmobile предназначен для перемещения целого дата-центра, где объёмы данных исчисляются петабайтами и более.

Передаточные устройства удобны для создания гибридных или мультиоблачных настроек. Например, устройство передачи данных от Amazon (AWS Snowball) поддерживает импорт и экспорт. Чтобы мигрировать в другое облако, пользователи могут экспортировать свои данные в устройство Snowball, а затем импортировать их в другое передаточное устройство для перемещения данных в GCP или Azure. Это может показаться неудобным, но даже когда возможно передавать данные через интернет между облаками, стоимость выгрузки данных делает это дорогостоящим предложением. Физические передаточные устройства являются более дешёвой альтернативой при значительных объёмах данных.

Помните, что передаточные устройства и услуги миграции данных предназначены для разовых событий получения данных и не рекомендуются для постоянных нагрузок. Если у вас есть рабочие нагрузки, требующие постоянного перемещения данных в гибридной или мультиоблачной среде, предполагается, что объёмы данных будут значительно меньше и передаваться потоками на постоянной основе.

Обмен данными

Обмен данными становится всё более популярным способом потребления данных (см. главы 5 и 6). Поставщики данных предлагают наборы данных сторонним подписчикам, либо бесплатно, либо за плату. Эти наборы данных часто предоставляются только для чтения, что означает, что вы можете интегрировать их с вашими собственными данными (и другими сторонними наборами данных), но вы не владеете предоставленным набором данных. В строгом смысле, это не получение данных, где вы получаете физическое владение набором данных. Если поставщик данных решит удалить ваш доступ к набору данных, вы больше не сможете им пользоваться.

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

С кем вы будете работать

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

Вышестоящие стейкхолдеры

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

Мы видим в этом текущее состояние дел проблему и значительную возможность. Инженеры данных могут улучшить качество своих данных, приглашая инженеров-программистов стать заинтересованными сторонами в результатах инженерии данных. Большинство инженеров-программистов хорошо осведомлены о ценности аналитики и науки о данных, но у них не всегда есть стимулы для прямого участия в усилиях по инженерии данных.

Простое улучшение коммуникации — это значительный первый шаг. Часто инженеры-программисты уже выявили потенциально ценные данные для последующего использования. Открытие канала связи поощряет инженеров-программистов приводить данные в форму, удобную для потребителей, и сообщать об изменениях данных, чтобы предотвратить регрессии в конвейерах.

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

Нижестоящие стейкхолдеры

Кто является конечным потребителем данных? Инженеры данных сосредоточены на специалистах по данным и технологических лидерах, таких как учёные-аналитики, аналитики и технические директора. Однако они также должны помнить о более широком круге бизнес-заинтересованных сторон, таких как директора по маркетингу, вице-президенты по цепочкам поставок и генеральные директора.

Слишком часто мы видим, как инженеры данных занимаются сложными проектами (например, шинами потоковой передачи данных в реальном времени или сложными системами данных), в то время как менеджеры по цифровому маркетингу в соседнем офисе вынуждены вручную загружать отчёты из Google Ads. Рассматривайте инженерию данных как бизнес и понимайте, кто ваши клиенты. Часто базовая автоматизация процессов получения данных имеет значительную ценность, особенно для отделов, таких как маркетинг, которые контролируют огромные бюджеты и находятся в центре доходов компании. Базовая работа по получению данных может показаться утомительной, но предоставление ценности этим ключевым частям компании откроет больше бюджета и более интересные долгосрочные возможности в области инженерии данных.

Инженеры данных также могут пригласить руководителей высшего звена к участию в этом коллаборативном процессе. По значительной причине культура, основанная на данных, весьма популярна в кругах бизнес-лидеров. Однако именно инженеры данных и другие специалисты по данным должны направлять руководителей, предлагая лучшую структуру для бизнеса, ориентированного на данные. Это означает коммуникацию ценности снижения барьеров между производителями данных и инженерами данных, поддержку руководителей в разрушении силосов и установлении стимулов для создания более единой культуры, ориентированной на данные.

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

Фоновые процессы

Почти все фоновые процессы касаются этапа поглощения данных, но мы выделим здесь самые значимые из них.

Безопасность

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

Рассмотрите, где находятся данные и куда они направляются. Данные, которые необходимо перемещать внутри вашей виртуальной частной сети (VPC), должны использовать безопасные конечные точки и никогда не покидать пределы VPC. Используйте VPN или выделенное частное соединение, если вам нужно отправлять данные между облаком и локальной сетью. Это может стоить денег, но безопасность — это хорошее вложение. Если ваши данные передаются через публичный интернет, убедитесь, что передача зашифрована. Всегда хорошей практикой является шифрование данных при передаче.

Управление данными

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

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

Одним из возможных решений, над которым мы, авторы, размышляли некоторое время, является подход, пионер которого — система контроля версий Git. Когда Линус Торвальдс разрабатывал Git, многие из его решений были вдохновлены ограничениями системы Concurrent Versions System (CVS). CVS полностью централизована; она поддерживает только одну официальную версию кода, хранящуюся на центральном сервере проекта. Чтобы сделать Git действительно распределённой системой, Торвальдс использовал концепцию дерева; каждый разработчик мог поддерживать свою обработанную ветку кода, а затем объединять её с другими ветками или из них.

Несколько лет назад такой подход к данным был немыслим. Локальные системы MPP обычно работают на пределе возможностей хранения. Однако хранение дешево в условиях больших данных и облачных хранилищ данных. Можно довольно легко поддерживать несколько версий таблицы с разными схемами и даже разными преобразованиями вверху по цепочке. Команды могут поддерживать различные «разработочные» версии таблицы, используя инструменты оркестрации, такие как Airflow; изменения схемы, преобразования вверху по цепочке и изменения кода могут появляться в разработочных таблицах до официальных изменений в основной таблице.
Этика, конфиденциальность и соответствие требованиям
Клиенты часто просят нашего совета по шифрованию конфиденциальных данных в базах данных, что обычно приводит нас к фундаментальному вопросу: нужны ли вам конфиденциальные данные, которые вы пытаетесь зашифровать? Как оказывается, этот вопрос часто упускается из виду при создании требований и решении проблем.

Инженеры данных всегда должны задавать себе этот вопрос при настройке конвейеров получения данных. Они неизбежно столкнутся с конфиденциальными данными; естественное стремление — получать их и передавать на следующий этап конвейера. Но если эти данные не нужны, зачем их вообще собирать? Почему бы просто не удалить конфиденциальные поля перед хранением данных? Данные не могут утечь, если их никогда не собирали.

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

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

Бесконтактное производство — это идеал, к которому должны стремиться инженеры, но ситуации неизбежно возникают, которые не могут быть полностью решены в средах разработки и тестирования. Некоторые ошибки могут быть невоспроизводимы без просмотра живых данных, вызывающих регрессию. Для таких случаев введите процесс «разбитого стекла»: требуйте, чтобы как минимум два человека одобрили доступ к конфиденциальным данным в производственной среде. Этот доступ должен быть строго ограничен конкретной проблемой и иметь срок истечения.

Наш последний совет по конфиденциальным данным: будьте осторожны с наивными технологическими решениями человеческих проблем. И шифрование, и токенизация часто рассматриваются как волшебные пули для конфиденциальности. Большинство облачных систем хранения и почти все базы данных шифруют данные по умолчанию как в состоянии покоя, так и при передаче. Обычно мы не видим проблем с шифрованием, а проблемы с доступом к данным. Решение ли в том, чтобы применить дополнительный слой шифрования к одному полю или контролировать доступ к этому полю? В конце концов, всё равно нужно строго управлять доступом к ключу шифрования. Существуют законные случаи использования шифрования отдельных полей, но остерегайтесь ритуалистического шифрования.

Что касается токенизации, используйте здравый смысл и оценивайте сценарии доступа к данным. Если у кого-то есть электронная почта одного из ваших клиентов, сможет ли он легко хэшировать её и найти клиента в ваших данных? Бездумное хэширование данных без использования соли (salting) и других стратегий может не обеспечить такой уровень защиты конфиденциальности, как вы думаете.

DataOps

Надёжные конвейеры данных — это краеугольный камень жизненного цикла инженерии данных. Когда они выходят из строя, все нижестоящие зависимости останавливаются. Хранилища данных и озёра данных не пополняются свежими данными, и учёные-аналитики и аналитики не могут эффективно выполнять свою работу; бизнес вынужден действовать вслепую.

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

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

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

К сожалению, универсального плана реагирования на сбои сторонних сервисов не существует. Если вы можете переключиться на другие серверы, предпочтительно в другой зоне или регионе, обязательно настройте это.
Если ваши процессы получения данных построены внутри компании, у вас есть надлежащее тестирование и автоматизация развёртывания, чтобы гарантировать, что код работает в продакшене? И если код окажется ошибочным или выйдет из строя, сможете ли вы откатиться к работающей версии?
Тесты качества данных
Мы часто говорим, что данные — это «тихий убийца». Если качественные и достоверные данные являются основой успеха современных бизнесов, то использование плохих данных для принятия решений гораздо хуже, чем отсутствие данных вообще. Плохие данные нанесли бизнесам неисчислимый ущерб; такие катастрофы, связанные с данными, иногда называют «датастрофами» (datastrophes).

Данные энтропийны; они часто изменяются неожиданными способами без предупреждения. Одно из принципиальных различий между DevOps и DataOps заключается в том, что мы ожидаем регрессий в программном обеспечении только при развёртывании изменений, тогда как данные часто демонстрируют регрессии независимо из-за событий, находящихся вне нашего контроля.

DevOps-инженеры обычно могут обнаруживать проблемы, используя бинарные условия. Превысила ли частота сбоев запросов определённый порог? А как насчёт задержки ответа? В сфере данных регрессии часто проявляются как тонкие статистические искажения. Является ли изменение статистики поисковых запросов результатом поведения клиентов? Или это следствие всплеска бот-трафика, который прошёл незамеченным? Или, возможно, это результат инструмента тестирования сайта, развёрнутого в другой части компании?

Как и системные сбои в DevOps, некоторые регрессии данных видны сразу. Например, в начале 2000-х Google предоставлял сайтам поисковые запросы, когда пользователи приходили с поиска. В 2011 году Google начал скрывать эту информацию в некоторых случаях, чтобы лучше защитить конфиденциальность пользователей. Аналитики быстро заметили, как «не предоставлено» начало появляться в верхних строках их отчётов.

На самом деле опасные регрессии данных могут быть незаметными и могут исходить как изнутри, так и извне компании. Разработчики приложений могут изменить значение полей базы данных, не достаточно проинформировав об этом команды данных. Изменения данных от сторонних источников могут остаться незамеченными. В лучшем случае отчёты ломаются очевидным образом. Часто бизнес-метрики искажаются без ведома принимающих решения.

По возможности, работайте с инженерами-программистами, чтобы устранять проблемы с качеством данных на источнике. Удивительно, сколько проблем с качеством данных можно решить, соблюдая базовые лучшие практики в инженерии программного обеспечения, такие как ведение журналов для отслеживания истории изменений данных, проверки (например, на null-значения) и обработка исключений (try, catch и т.д.).

Традиционные инструменты тестирования данных обычно построены на простой бинарной логике. Появляются ли null-значения в не-null-поле? Появляются ли новые, неожиданные элементы в категориальном столбце? Статистическое тестирование данных — это новая область, но она, вероятно, значительно вырастет в ближайшие пять лет.

Оркестрация

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

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

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

Программная инженерия

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

За кулисами получение данных чрезвычайно сложно, часто с командами, работающими с открытыми фреймворками, такими как Kafka или Pulsar, или крупнейшими технологическими компаниями, использующими собственные или модифицированные решения для получения данных. Как обсуждалось в этой главе, управляемые коннекторы данных, такие как Fivetran, Matillion и Airbyte, упростили процесс получения данных. Инженеры данных должны использовать лучшие доступные инструменты — в основном управляемые инструменты и сервисы, которые выполняют за вас большую часть тяжёлой работы, — и развивать высокую компетентность в разработке программного обеспечения в областях, где это важно. Стоит использовать правильные процессы контроля версий и проверки кода и внедрять соответствующие тесты даже для кода, связанного с получением данных.

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

Заключение

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

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

Дополнительные ресурсы

■ Страница «Connections and Sync Modes», Airbyte
■ Глава 6 из «Batch Is a Special Case of Streaming» из Introduction to Apache Flink, Ellen Friedman, Kostas Tzoumas (O’Reilly)
■ «The Dataflow Model: A Practical Approach to Balancing Correctness, Latency, and Cost in Massive-Scale, Unbounded, Out-of-Order Data Processing», Tyler Akidau
■ Страница «Streaming Pipelines» на сайте Google Cloud
■ Документация Microsoft «Snapshot Window (Azure Stream Analytics)»

■ Другие статьи на тему Базы данных

Показать еще