Data Lake на AWS: збираємо вимоги та будуємо ingestion pipeline

Привіт! Мене звуть Ігор Козлов і я Python Software Engineer в міжнародній ІТ-компанії Levi9. Останні чотири роки я працюю над створенням data solutions для наших замовників, які хочуть отримувати більше користі з даних. Для цього необхідно побудувати інфраструктуру для обробки даних, яка має бути гнучкою, захищеною та працюватиме без помилок.

Але, з мого досвіду, багато компаній одразу переходить до створення системи, не проаналізувавши, які вимоги до неї та які зміни необхідні бізнесу, що отримати найкращий результат.

У серії статей про data solutions я опишу основні етапи проєктування системи для роботи з даними на AWS (Amazon Web Services) — отримання вимог до даних, їх обробку, зберігання та використання. У першій частині матеріалу я розберу проблемні питання та наведу приклади ефективних рішень, які ми з командою виявили під час реалізації проєктів. Стаття буде корисною розробникам, які вже працюють із data engineering або тільки планують побудувати таке рішення для замовника.

Список із ключових питань

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

Щоб створити рішення, яке задовольняє конкретні потреби клієнтів, слід зібрати багато інформації й тільки потім переходити до розробки архітектури. Якщо цього не зробити, можна опинитися в ситуації, коли всю систему треба перебудовувати спочатку.

Я зібрав найпоширеніші запитання, які допоможуть краще зрозуміти клієнта та проблему, яку він хоче розв’язати. Наприклад:

  • Які бізнес-задачі мають вирішуватись завдяки зберіганню та обробці даних?
  • Чи наявна в компанії стратегія управління даними (Data Governance Strategy)?
  • З якими типами даних доведеться працювати?
  • Хто буде постачальниками та споживачами даних (data producers and consumers)?
  • З якою кількістю даних ми працюватимемо?
  • Чи маємо справу з конфіденційними даними, наприклад, інформація про клієнта?

Поглиблюючись у бізнес-кейси

Складність будь-якої системи дуже залежить від вимог бізнесу. Ось чому важливо одразу розуміти всі потреби й задачі.

У мене була ситуація, коли замовник хотів побудувати Data Lake як центральне сховище даних, які можуть використовуватись в майбутньому. Ми з ним обговорили деталі, зібрали відомості про датасети та почали розробку. А коли вже отримали перші дані, виявилося, що для інших департаментів дуже важлива якість цих даних, і вони вже хочуть використовувати їх у своїх процесах. На той час це не було передбачено в нашому рішенні. Тобто у замовника не було єдиного бачення роботи з даними та процес не був узгоджений між різними департаментами. Як результат — ми переробляли наше рішення.

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

Image Credit: Usama Shamma

Оптимальна ситуація — це наявність в компанії стратегії управління даними. Ця стратегія відрізняється в більшості компаній, але зазвичай вона має включати в себе:

  • KPI даних;
  • вимоги до якості даних;
  • відповідність регулятивним вимогам;
  • процес вирішення інцидентів з даними;
  • загальні архітектурні принципи зі зберігання та обробки даних.

Для того, щоб успішно впровадити цю стратегію, всі рівні компанії мають бути ознайомлені з нею та дотримуватися її.

Створення стратегії управління даними є важливим першим кроком до успішного управління та отримання business value з даних.

Розуміння типів даних

Існує два основних типи отримання даних — пакетний і потоковий, а також два базові формати даних — структурований і неструктурований.

При пакетному завантаженні ми розраховуємо на отримання даних за один раз. Це зручно для роботи з великим обсягом інформації, яку не потрібно аналізувати в режимі реального часу. Наприклад, це дані про замовлення чи оплату послуг.

У той час при потоковому введенні дані доставляються частинами безперервно. Тому їх можна одразу аналізувати. Яскравий приклад — аналіз log-файлів, де потрібно вжити заходів, щойно система виявила помилку.

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

Data producers та consumers

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

Сервіси, наприклад Kinesis або Kafka, з якими ми познайомимось пізніше, мають багато вбудованих рішень для зовнішніх систем, таких як Google Analytics, баз даних тощо. Вони просто інтегруються з багатьма third-party сервісами та дозволяють легко отримати дані та зберегти їх у нашій дата платформі.

Якщо ми знаємо особливості роботи data producers і consumers, їхні можливості імпортувати чи експортувати дані, то можемо обрати правильний сервіс і зменшити час на розробку.

Перевірка обсягу даних

Обсяг даних впливає на те, які сервіси та технології ми використовуємо. Якщо перед нами буде стояти вимога обробляти дані з простими трансформаціями, розміром, скажімо, до 1 ГБ, то ми цілком можемо використати AWS Lambda. Але щойно ми починаємо отримувати значно більший обсяг або логіка включає поєднання великих датасетів — ми досягаємо сервісних лімітів і не можемо просто використовувати Lambda як раніше. Виникає необхідність інтегрувати інше рішення в нашу архітектуру.

Щоб зробити правильний вибір, ви повинні знати, яку кількість даних маєте та як вам потрібно їх обробляти. Оптимальним рішенням може бути використання декількох сервісів, які зможуть найбільш ефективно обробляти певний об’єм даних.

Конфіденційні дані

Якщо клієнти дотримуються стандартів GDPR чи HIPAA, розробник має заздалегідь подумати про анонімізацію даних і бути готовим до запитів на вилучення персональних даних. Видалити один рядок інформації з великого об’єму даних — досить складна та витратна задача. Тому необхідно проєктувати систему так, щоб наші метадані мали інформацію про те, в яких саме даних є чутлива інформація та опис процесу роботи з ними, включаючи видалення за запитом.

Зібравши відповіді на ці питання, проаналізувавши їх та створивши стратегію управління даними, можна переходити безпосередньо до створення архітектури. Перший етап — побудова ingestion pipeline, тобто механізму завантаження даних у наше сховище.

Різниця між Data Lake та Data Warehouse

На основі вимог, які ми отримали від клієнта, постає питання: як зрозуміти, що нам потрібно — Data Lake чи Data Warehouse? У чому суттєва різниця?

В Інтернеті ви знайдете багато порівнянь, які я б підсумував так: все залежить від бізнес-кейсів і типів даних. Якщо коротко — коли дані структуровані чи неструктуровані та зберігаються «про всяк випадок» для легкого застосування або для інших задач, які ще до кінця не відомі, — вам, швидше за все, допоможе Data Lake. Якщо дані структуровані, існують чіткі вимоги до якості, на цих даних побудовані певні бізнес-процеси — вам потрібен Data Warehouse.

У більшості клієнтів знайдуться дані для обох типів рішень.

Крім того, однаковий набір даних можна використовувати як в необробленому, так і в обробленому форматах. Для цих випадків нам потрібно створити комбіноване рішення. Наприклад, дані з Data Lake можна завантажувати та використовувати в Data Warehouse. Або ж інакше — зберігати дані у кілька етапів в Data Lake, беручи за основу якість даних, тобто бронзову, срібну та золоту області. «Бронзові» дані — це наші сирі дані, які ми отримуємо «as is». До «срібних» належать вже частково очищені дані відповідно до вимог. «Золоті» дані — дані, які ми вважаємо найбільш надійними та які можуть використовуватися в бізнес-процесах.

У випадку міксованого підходу ми маємо два потоки передачі даних: в Data Lake та в Data Warehouse. Другий потік можна розглядати як обробку даних.

Розглянемо перший потік даних. А почнемо зі Stream Injection.

Зазвичай основні вимоги до потокової передачі даних — це:

  • підтримувати різні джерела даних;
  • вміти аналізувати дані в режимі реального часу;
  • зберігати дані для подальшого використання.

З мого досвіду, одна з оптимальних та економічно ефективних архітектур може виглядати так:

Приклад архітектури потокової передачі даних

Тепер подивимося на складові цієї архітектури.

Імплементація на стороні data producer

Для потокового сервісу ми зазвичай вибираємо Kinesis Data Streams. Він дозволяє створювати персональні генератори даних за допомогою бібліотеки Kinesis Producer Library (KPL). Ви можете створити генератор даних для синхронного або асинхронного використання. У ньому вже вбудована логіка групування, retry-механізм, розподілення на кілька потоків та деагрегації, тому вам не потрібно прописувати логіку самостійно. Крім цього, можна помістити дані в Kinesis Data Streams за допомогою API або SDK, але краще використовувати KPL.

На одному з проєктів ми використовували API Gateway з Kinesis як проксі, бо все спілкування між командами мало відбуватися через API. Проблеми, з якими ми зіткнулися в результаті, були такі:

  • Обмеження в 10 000 запитів на секунду. Щоб збільшити обсяг потрібно було звернутися в службу підтримки AWS.
  • Ціна сервісу в випадку великої кількості запитів. Наприклад, 1 мільярд запитів до HTTP API коштував додаткових 1000 доларів на місяць.

Щоб оптимізувати витрати, ми почали використовувати PutRecordsBatch метод, який дозволив нам об’єднувати декілька пейлоадів (payload) в один. Це трохи знизило загальну вартість використання сервісів.

Робота з API Gateway також дала нам декілька переваг:

  • ми додавали ідентифікатор користувача (user-agent), IP-адресу та іншу корисну інформацію до тіла запиту без залучення дата продюсера;
  • також ми використали mapping templates для зміни структури запиту, що зробило обробку даних більш зручною.

Але в більшості випадків використання KPL — це найпростіший варіант, щоб створити data producer для потокової передачі даних. API Gateway варто використовувати, коли у вас мала кількість запитів.

Якщо ж є необхідність бути cloud agnostic, тобто не залежати від сервісів конкретного хмарного провайдера, можна обрати Apache Kafka як альтернативу. Він надає ті самі можливості, які ми розглянули для Kinesis, але, при необхідності, цей сервіс простіше мігрувати до іншого хмарного сховища. Ви можете як розвернути Kafka у Kubernetes, так і використати AWS MSK — Amazon Managed Streaming for Apache Kafka.

Аналітика в режимі реального часу

Ваша компанія хоче відстежувати трафік на вебсайті? Або виявляти аномалії в поведінці користувачів? Можливо, ви хочете відстежувати результати A/B-тестувань у режимі реального часу? Amazon Kinesis Data Analytics може допомогти вам у цьому та надати ще більше інформації.

Він може обробляти дані менше, ніж за секунду. Завдяки такій високій швидкості ви можете виконувати подібні до SQL запити поверх ваших даних, перетворювати/фільтрувати або збирати дані та розміщувати їх безпосередньо в DynamoDB. Звідти їх можна отримати за допомогою різних інформаційних панелей та інструментів аналітики, наприклад Tableau. Коли дані візуалізуються, це дає нам ще більше інформації про їхню корисність, оптимальність використання та пов’язані бізнес-процеси.

Зберігання потокових даних

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

Формат файлу оптимально обрати стовпчастий. Наприклад, Apache Parquet. Ті самі дані у форматі Parquet можуть бути до 100 разів меншими, ніж дані у CSV-форматі. Крім того, стовпчасті формати оптимізовані для запитів, які зчитують певні стовпці з таблиці. Наприклад, оптимальний розмір файлів для AWS Athena — 200-500 MB. Основна ідея — це не мати багато малих файлів, на відкриття з S3 яких витрачається багато часу, та не використовувати великі файли, які будуть довго завантажуватись.

Kinesis Data Firehose може перетворювати ваші дані у Parquet формат автоматично — вам потрібно лише вказати таблицю в Glue Data каталозі, згідно з якою буде відбуватися трансформація. Якщо вам потрібно додатково провалідувати дані, додати якусь інформацію — ви можете написати спеціальну лямбда-функцію, яка виконуватиме це до того, як дані будуть завантажені в сховище S3.

Щоб вибрати оптимальний об’єм для зберігання даних, слід відповісти на наступні питання:

  • Який тип запитів я збираюся виконувати щодо цих даних?
  • Які параметри даних для мене найважливіші?
  • Які фільтри та агрегації я буду створювати на основі цих даних?

Наприклад, якщо вам потрібно виконувати запити щодо певного проміжку часу, то ви, ймовірно, захочете зберігати їх у вигляді «рік/місяць/день». Але що робити, якщо деякі дані треба розділити по годинах? Або інший набір даних доставлятиметься лише раз на місяць?

Крім часового розбиття, важливо ще розбивати інформацію по характеристиках, які будуть використовуватися найчастіше для запитів. Наприклад, якщо ви маєте каталог товарів, і запити зазвичай будуть відбуватися всередині певної категорії товарів, то добре буде використовувати розбиття товарів по категоріях. Але, наприклад, якщо важливіше буде робити запити в рамках окремого магазину (а вони, зазвичай, мають багато категорій), то краще використовувати розбиття по магазинах, щоб уникнути запитів із об’єднанням декількох категорій.

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

Пакетні дані

Коли ми говоримо про пакетне завантаження даних, зазвичай все простіше. Ідея полягає в тому, щоб завантажити дані на S3. Звідти їх можна буде забрати для майбутньої обробки. Варто звернути увагу на кілька особливостей цього процесу:

  • використовувати S3 multipart upload для великих файлів;
  • розділити дані на кілька файлів і завантажувати їх паралельно;
  • вибрати оптимальний формат розділення (partition) даних на основі того, для чого вони використовуватимуться;
  • розділити S3 bucket за data producers — ви можете просто обмежити доступ до префіксу за допомогою політики IAM

Діаграма архітектури для цього виду передачі даних може виглядати так:

Приклад архітектури з отримання пакетних даних

Виглядає набагато простіше, поки ми не перейшли до етапу обробки даних. Під час пакетної обробки користувачі можуть експортувати набори даних розміром 10 МБ або 10 ТБ. Тому ви маєте обробляти їх найбільш рентабельним способом.

Як ви думаєте, якими будуть наші критерії для вибору оптимального механізму обробки даних? Чи будуть відмінності для пакетного та потокового введення?

У другій частині матеріалу я відповім на ці запитання. Ми також подивимося на стек обробки нашого рішення.

P. S: Думаєте, що Lakehouse спочатку — це просто мем? Тоді перегляньте Delta Lake, Lakehouse, що розв’язує проблеми наявні у Data Lake та Data Warehouse, та має переваги обох.

👍НравитсяПонравилось14
В избранноеВ избранном7
LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Ігор, дякую за статтю! А як так вийшло, що ви по-суті солюшн інженером по дата стораджам стали? Мені самому було б цікаво в ту сторону карґєри розвинутись, але поки не знаю легких шляхів.

Дякую за відгук!
Я для себе вивчав Python та Machine Learning, тому вже був деякий досвід саме з мовою програмування. Також ми на проекті активно використовували AWS та я готувався до сертифікації — це дало необхідний бекграунд по самим сервісам. І, звісно, допомога дата архітектів з Levi9, які ревювили мої рішення та допомогали.
На мій погляд, потрібно підготувати технічний бекграунд,а потім змінити стек з яким працюєте. І це, звісно, буде простіше зробити на поточному місці роботи, якщо можливо.
Якщо Вас цікавлять матеріали які допоможуть розібратися в темі — напишіть, я Вам відправлю

А почнемо зі Stream Injection

Виправте, будь-ласка. Injection тут явно не в контексті.

Цікава стаття, дякую.

Пізнавально. Чекаю продовження

Якщо перед нами буде стояти вимога обробляти дані з простими трансформаціями, розміром, скажімо, до 1 ГБ

1Gb per sec?

Не вистачає приземленого опису на пальцях

Аналітика в режимі реального часу

Для чого це може знадобитись?
Я знаю тільки тільки один приклад — самописна платформа для показу реклами під навантаженням з арбітражем
І то там можна, без погіршення функціоналу, зрізати кути і зробити псевдо ріалтайм

Ті самі дані у форматі Parquet можуть бути до 100 разів меншими, ніж дані у CSV-форматі

gz -9 ?

В нашому випадку аналітика в реальному часі потрібна була для аналізу спеціальних пропозицій від партнерів. Так, звичайної гугл аналітики та таг менеджеру було замало)
Звісно, компресія типу gzip, lzop або bzip2 ще більше зменшать розмір файлу, але якщо початковий файл в parquet форматі він буде все одно легший за аналогічний в csv, навіть використовуючи стиснення. Ще важливо враховувати де файли застосовуються, наприклад які формати та стиснення підтримує Redshift та Athena. Про це буде більше в другій частині статті

gz — 9 : Основное преимущество паркета в том что в файле храниться колоночный индекс который используется на этапе его чтения Compute Engine что сильно помогает оптимизировать время выполнения запроса. При этом уменьшение размера самого файла как раз таки и достигается с помощью таких алгоритмов компрессии как GZ или Snappy. То есть при чтении каждого файла Compute Engine сперва сделает декомпрессию, а после использует индекс для того чтоб попробовать минимизировать область файла которую необходимо прочитать

Аналітика в режимі реального часу добра для торгів криптовалютою.

Надто дороге рішення, є варіанти як це простіше, краще і дешевше можна налаштувати а так стаття норм, дякую!

Згоден, в плані ціни можна оптимізувати (наприклад, не використовувати API Gateway), але тут також накладаються внутрішні вимоги клієнта щодо розробки та, подекуди, необхідність залучення девопса, якщо піднімати все самостійно

Интересно о каких вариантах идет речь?

Подписаться на комментарии