Основи та базова теорія
Практика та поглиблені знання
Архітектура та оптимізація
Big Data (великі дані) — це великі обсяги даних, які обробляються з високою швидкістю та мають високу різноманітність (структуровані, напівструктуровані та неструктуровані).
Від традиційних підходів відрізняються:
Концепція 5V описує основні характеристики великих даних:
Існує багато BI-інструментів (Business Intelligence) для візуалізації даних. Найпопулярніші з них:
База даних (БД) — це впорядкований масив інформації, до якого можна отримати швидкий і структурований доступ.
Вона використовується для:
Основні типи баз даних:
Мова SQL складається з 4 основних підгруп команд (блоків):
user_id).RIGHT JOIN повертає абсолютно всі рядки з правої таблиці (тієї, що вказана після оператора JOIN), а також лише ті рядки з лівої, які відповідають умові ON.
Якщо збігу в лівій таблиці немає, у відповідних колонках результату будуть заповнені значення NULL.
Відмінність від інших: По суті, він виконує ту саму роботу, що й LEFT JOIN, просто дзеркально. На практиці програмісти і дата-інженери майже завжди віддають перевагу LEFT JOIN (змінюючи порядок таблиць місцями), оскільки читати запити зліва направо набагато зручніше та інтуїтивніше для логіки людини.
Обидві команди працюють із групами (агрегаціями), але принципово відрізняються результатом виводу:
SELECT department_name, SUM(salary) GROUP BY department_name — видасть
лише 1 рядок на кожен департамент).Ці таблиці є основою моделі "Зірка" (Star Schema) у сховищах даних:
Ітератор (Iterator) — це об'єкт, який реалізує протокол ітерації (методи __iter__() та __next__()). Дозволяє перебирати елементи колекції по одному.
Генератор (Generator) — це простіший спосіб створення ітераторів. Створюється за допомогою звичайної функції, але замість return повертає значення через yield.
Різниця та застосування: Генератори є підвидом ітераторів. Вони використовуються для обробки великих наборів даних або файлів (послідовно, рядок за рядком), оскільки не завантажують усі дані в пам'ять (RAM) одночасно.
[ ]. Є мутабельними, тобто їх можна змінювати після створення (додавати, видаляти, редагувати елементи).( ). Є іммутабельними (незмінними). Після створення жоден елемент не можна змінити. Працюють трохи швидше ніж списки, і через їхню незмінність їх можна використовувати як ключі у словниках (dict).Лямбда-функція — це невелика анонімна функція (функція без імені), яка може приймати будь-яку кількість аргументів, але містить лише один вираз. Будується через ключове слово lambda.
Коли використовувати: Ідеально підходять, коли функція потрібна лише на короткий проміжок часу і її логіка дуже проста. Наприклад, як аргумент для функцій map(), filter() або при сортуванні sorted(list, key=lambda x: x[1]).
Lazy evaluation — це механізм Apache Spark, який відкладає реальне виконання коду до того моменту, поки не знадобиться результат.
Яку роль відіграє: Поки ви робите трансформації (map, filter), Spark лише запам'ятовує їх, будуючи граф виконання (Lineage Graph/DAG). Він не починає рахувати дані, поки ви не викличете "дію" (Action, наприклад collect() або count()). Це дозволяє Spark застосувати глобальні оптимізації і знайти найбільш ефективний шлях обчислення.
map(), filter(), groupBy(), join().count(), collect(), show(), write().Amazon S3 (Simple Storage Service) — це хмарне об'єктне сховище. Воно призначене для зберігання і завантаження будь-яких обсягів даних з будь-якого місця в Інтернеті.
У світі Big Data S3 найчастіше використовується як базове надійне та дешеве сховище підприємства і є фундаментом для побудови Data Lake. Дані звідти прямо читаються інструментами на зразок Spark, Athena чи Redshift.
AWS Lambda — це Serverless обчислювальний сервіс, який дозволяє запускати код (функції) без виділення серверів і управління ними (все робиться автоматично). Ви платите лише за мілісекунди, коли код фактично виконується.
Різниця:
Data Lake (Озеро даних) — це централізоване сховище, що дозволяє зберігати всі структуровані, напівструктуровані та неструктуровані дані у їхньому первозданному (сирому) вигляді при будь-якому масштабі.
Для чого використовується:
DAG (Спрямований ациклічний граф) — це набір задач (tasks) та залежностей між ними, де кожна задача виконується у строго визначеному порядку. "Ациклічний" означає, що потік виконання ніколи не повертається назад і не створює циклів.
У таких системах, як Airflow, DAG репрезентує весь Data Pipeline в цілому.
Ідемпотентність — це характеристика операції чи задачі, при якій її багаторазове виконання призводить до того ж самого результату, що й одноразове виконання.
Чому це важливо: Якщо ваш Batch Job впаде посередині через помилку мережі, і ви його перезапустите (зробите retry), він не повинен задублювати дані, які встиг записати під час першої (невдалої) спроби.
PEP 8 — це офіційний "Style Guide" (звід правил щодо стилю) для написання коду на Python.
Він визначає базові правила форматування: відступи (4 пробіли), максимальну довжину рядка (79 символів), правила іменування змінних (snake_case) та класів (CamelCase), кількість порожніх рядків між функціями тощо. Це робить код читабельним для всіх розробників.
int (цілі), float (дробові), complex (комплексні).str (рядок).bool (True/False).list (список), tuple (кортеж), range.dict (пари ключ-значення, хешмова).set (унікальні елементи), frozenset.Магічні методи (Dunder methods) — це вбудовані методи класу, назви яких починаються і закінчуються подвійним підкресленням (наприклад, __init__, __str__, __len__, __add__).
Вони дозволяють налаштувати базову поведінку об'єктів вашого класу. Наприклад, щоб об'єкт можна було роздрукувати через print() (викличеться __str__) або порахувати його довжину через len() (викличеться __len__).
Comprehensions — це короткий, "елегантний" і швидкий спосіб генерації нових списків, словників чи множин на основі існуючих ітерованих об'єктів в один рядок.
[x**2 for x in range(5) if x % 2 == 0] -> [0, 4, 16]{x: x**2 for x in range(3)} -> {0: 0, 1: 1, 2: 4}Екосистема Spark включає 5 основних модулів:
Це ієрархія виконання вашого коду на кластері:
collect() або write()). Це найвищий рівень.groupBy або join створюють новий Stage.Партиція — це логічний "шматок" (фрагмент) великого набору даних (RDD/DataFrame), який обробляється окремо на одному вузлі кластера.
Важливість: Вони дозволяють обробляти гігантські файли паралельно. Якщо у вас файл на 100 ГБ і ви розбили його на 100 партицій, то 100 процесорів зможуть читати його водночас. Проте якщо партицій занадто мало — кластер буде простоювати, а якщо забагато — з'явиться overhead (перевитрата ресурсів) на управління задачами.
CI/CD — це практика DevOps для автоматизації процесів поставки коду:
Kubernetes (K8s) — це потужна open-source система для оркестрації (управління) контейнеризованими додатками.
Замість того, щоб вручну запускати 50 Docker контейнерів, ви віддаєте їх Kubernetes. Він автоматично розгортає їх на доступних серверах, масштабує вгору при зростанні трафіку, перезапускає в разі падіння (Self-healing), та забезпечує балансування навантаження між ними.
Docker — це платформа для створення та запуску додатків у контейнерах.
Контейнер — це ізольований, легкий пакет коду, який містить абсолютно все необхідне для запуску вашого Pipeline (код, Python, бібліотеки, системні утиліти, файли конфігурації). Завдяки Docker вирішується класична проблема: "У мене на ноутбуці працювало, а на сервері чомусь зламалося!". Контейнер буде працювати абсолютно однаково на будь-якій машині.
JSON (JavaScript Object Notation): Це формат передачі даних у вигляді "ключ-значення". Він напівструктурований, може містити вкладені масиви та інші об'єкти. Переважно використовується в REST API.
CSV (Comma-Separated Values): Текстовий формат, де дані розділені комами (або іншим символом, наприклад ; чи |). Він лінійний і плоский (кожен рядок - новий запис). Легко читається в Excel. Не підтримує складні типи даних та вкладеності.
REST API — це архітектурний стиль взаємодії компонентів через HTTP-запити. Зазвичай повертає дані у форматі JSON.
Data Engineers використовують API для інтеграції (Data Extraction) — написання скриптів на Python (через бібліотеку requests), які "викачують" дані з зовнішніх сервісів (Facebook Ads, Salesforce, Jira) та складають їх у Data Lake.
[]: Впорядкована колекція елементів, яку можна змінювати (mutable). Підтримує дублікати.(): Впорядкована колекція, але незмінна (immutable). Працює швидше за список, часто використовується для повернення декількох значень з функції.{}: Невпорядкована колекція унікальних елементів. Ідеальна для видалення дублікатів (set(my_list)).{"key": "value"}: Зберігає пари ключ-значення. Ключем може бути лише незмінний тип.WHERE. Кожне видалення записується в лог транзакцій. Це DML операція (її можна відкотити за допомогою ROLLBACK).Обидва оператори використовуються для фільтрації даних, але на різних етапах запиту:
WHERE age > 18.HAVING COUNT(orders) > 5.Virtual Environment (venv) — це ізольоване середовище для окремого Python-проєкту.
Воно дозволяє запускати проєкти з різними версіями одних і тих же бібліотек на одній машині (наприклад, Проєкт А вимагає pandas 1.0, а Проєкт Б — pandas 2.0). Без віртуального середовища це спричинило б конфлікт залежностей.
CREATE, ALTER, DROP, TRUNCATE.INSERT, UPDATE, DELETE. Запити SELECT часто виділяють в окрему групу DQL (Data Query Language).TCL — це команди для управління транзакціями у базі даних (управління DML-запитами):
COMMIT: Фіксує (зберігає) всі зміни, зроблені в поточній транзакції назавжди.ROLLBACK: Відкочує всі зміни з моменту старту транзакції, якщо сталася помилка.Stage Zone (Staging) — це тимчасова, проміжна зона зберігання даних між джерелами даних (Data Sources) та Сховищем Даних (Data Warehouse).
Завдання: Дані зчитуються з багатьох повільних або критичних джерел (наприклад, продакшн-БД) і швидко копіюються в Staging без жодних трансформацій. Це робиться для того, щоб не навантажувати джерело важкими обчисленнями під час очищення даних. Вже на Staging серверах дані безпечно об'єднуються та очищуються перед завантаженням у Сховище.
HDFS (Hadoop Distributed File System) — це розподілена файлова система ядра Hadoop.
Вона розбиває величезні файли на блоки (зазвичай по 128 МБ) і розподіляє їх між сотнями фізичних серверів (DataNodes) у кластері. Для забезпечення надійності кожен блок реплікується (дублюється) 3 рази на різних серверах. Якщо один сервер згорає — дані не втрачаються і система продовжує працювати (Fault Tolerance).
NoSQL (Not Only SQL) — це нереляційні БД, які не використовують стандартні таблиці з рядками та стовпцями.
Вони ідеальні для Big Data завдяки горизонтальному масштабуванню (легко додати нові сервери у кластер). Особливості:
Лямбда-функція — це маленька анонімна (без імені) функція, яка визначається одним рядком за допомогою ключового слова lambda.
Приклад: multiply = lambda x, y: x * y. Їх часто використовують як швидкі одноразові функції всередині інших методів, наприклад, під час сортування (sorted(list, key=lambda x: x[1])) або як User Defined Functions (UDF) у Pandas чи Spark.
Context Manager (Менеджер контексту) — це механізм у Python для зручного управління ресурсами, який гарантує автоматичне очищення/закриття ресурсу після його використання.
Найчастіше це оператор with open('file.txt') as f:. Якщо під час читання файлу відбудеться помилка або цикл закінчиться, контекстний менеджер автоматично викличе метод f.close(), щоб звільнити системний ресурс і не допустити витоку пам'яті (Memory Leak).
for. Під капотом він реалізує магічний метод __next__().yield замість return, або через генераторні вирази (x**2 for x in data). Перевага: Генератор не зберігає весь масив у пам'яті. Він видає по одному елементу лише тоді, коли його про це попросять. Це дозволяє Data-інженерам обробляти гігантські файли (по 100 ГБ) на ноутбуці з 8 ГБ RAM.Lazy Evaluation означає, що Spark взагалі нічого не робить і не обчислює дані, коли ви пишете тисячі перетворень (трансформацій filter(), join()). Він просто "записує" їх у план дій — Граф (DAG).
Дані починають реально читатися і оброблятися лише тоді, коли ви викликаєте спеціальну команду Дію (Action), наприклад show(), count() або write(). Це дозволяє оптимізатору (Catalyst) заздалегідь переглянути весь план і прибрати зайві кроки.
select(), filter(), groupBy().show(), collect(), write().Apache Spark може читати майже будь-який формат завдяки DataFrameReader. Найпопулярніші: CSV, JSON, Parquet, Avro, ORC.
Він також підтримує прямі підключення до реляційних баз даних (через JDBC/ODBC драйвери), а також бази даних NoSQL типу Cassandra чи MongoDB.
Pod (Под) — це найменший, найбазовіший об'єкт у Kubernetes, який ви можете створити або яким можна керувати.
Под — це логічна оболонка (обгортка) навколо одного або декількох тісно пов'язаних контейнерів (наприклад, Docker-контейнерів). Ці контейнери завжди запускаються разом на одному сервері, ділять спільну IP-адресу та ресурси збереження (Volumes), що дозволяє їм легко спілкуватися один з одним через localhost.
SQL (реляційні бази даних):
NoSQL (нереляційні бази даних):
Теорема CAP стверджує, що розподілена система зберігання даних може забезпечити лише дві з трьох наступних властивостей одночасно:
Так як у розподілених системах Partition tolerance (P) є обов'язковою, вибір стоїть між:
Колонкова база даних зберігає дані не по рядках (як традиційні RDBMS), а по колонках. Кожна колонка зберігається в окремому файлі або блоці на диску.
Використовується для:
Приклади: ClickHouse, Amazon Redshift, Google BigQuery, Snowflake.
Індекс — це структура даних (зазвичай B-tree), яка дозволяє швидко знаходити рядки в таблиці без перебору всіх даних (Full Table Scan), що критично для великих баз даних.
ACID гарантує надійність виконання транзакцій у реляційних БД:
Рівні ізоляції (Read Uncommitted, Read Committed, Repeatable Read, Serializable) регулюють баланс між швидкістю та захистом від аномалій при паралельному доступі (брудні чи фантомні читання).
Apache Spark працює значно швидше (у 10-100 разів) за MapReduce.
Чому? MapReduce після кожного кроку обробки (Map або Reduce) обов'язково зберігає проміжні результати на жорсткий диск (HDFS) для забезпечення надійності, що спричиняє величезні затримки через I/O (читання/запис диска).
Spark натомість використовує обробку In-Memory (у RAM). Він виконує максимум перетворень у пам'яті і записує дані на диск лише тоді, коли пам'ять закінчується або коли явно викликається дія (Action).
Вони обидва використовуються для збереження обчисленого RDD/DataFrame в пам'яті, щоб не перераховувати його при наступних зверненнях.
MEMORY_AND_DISK для
DataFrame та MEMORY_ONLY для RDD.MEMORY_ONLY,
MEMORY_AND_DISK, DISK_ONLY або навіть додати реплікацію
(MEMORY_ONLY_2).DAG (Directed Acyclic Graph) — це колекція всіх задач (tasks), які ви хочете запустити, організована у вигляді графа, який відображає їхні залежності. "Ациклічний" означає, що потік не може зациклюватись (йти по колу).
Основні типи Операторів (будівельних блоків задач):
PythonOperator, BashOperator, EmailOperator).
MySqlToS3Operator).FileSensor).
Обидва це бінарні формати для Big Data, але призначені для різних завдань:
Індекс — це спеціальна структура даних (часто B-Tree), яка дублює частину таблиці та зберігається в пам'яті у посортованому вигляді, що дозволяє БД знаходити рядки надзвичайно швидко замість сканування всієї таблиці (Full Table Scan).
Автоматичне створення: У більшості реляційних БД (наприклад, Postgres, MySQL) індекси автоматично створюються лише для стовпців з PRIMARY KEY (PK) та стовпців з обмеженням UNIQUE. Для FOREIGN KEY (FK) індекси не створюються автоматично — їх потрібно додавати вручну.
UPSERT (Update or Insert) — це логічна операція: "якщо запис з таким ключем вже існує — онови його. Якщо його ще немає — встав (створи) новий". Це ключовий механізм для створення ідемпотентних пайплайнів.
Реалізація у Postgres: Використовується оператор ON CONFLICT.
INSERT INTO users (id, name) VALUES (1, 'Ivan') ... ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name;
MERGE — це більш потужна і стандартизована версія UPSERT (також називається SCD - Slowly Changing Dimensions merging). Він дозволяє злити (merge) дані з "Source" таблиці до "Target" таблиці.
Окрім UPDATE і INSERT, MERGE підтримує операцію DELETE, і дозволяє встановлювати складні умови мeтчу (наприклад: WHEN MATCHED AND source.status = 'deleted' THEN DELETE). MERGE активно використовується у Сховищах Даних та Delta Lake системах.
Декоратор — це функція-обгортка, яка приймає іншу функцію (або метод) як аргумент і дозволяє динамічно додати до неї нову логіку до чи після виконання, не змінюючи вихідний код цієї функції.
Використовується із символом @ (наприклад, @property, @staticmethod або власні декоратори для логування, таймерів виконання чи Retry-обгорток).
map(), filter(), union().groupBy(), join(), orderBy().За замовчуванням кожна задача (Task) в Airflow ізольована. Для передачі стану або невеликих даних використовується механізм XCom (Cross-Communication).
Коли Task повертає значення (або явно робить xcom_push()), воно серіалізується і зберігається в мета-базу даних Airflow (Postgres/MySQL). Наступний Task може витягнути це значення (через xcom_pull()).
Важливо: XCom призначений *лише* для метаданих (ID файлів, дати, шляхи на S3). Через нього категорично не можна(і часто неможливо через ліміт метабази) ганяти Pandas DataFrame чи великі об'єми даних.
Віконні функції поділяються на 3 основні групи:
SUM(), AVG(), MAX(), MIN() OVER (...). Агрегують дані, але залишають деталі рядків.ROW_NUMBER(): Дає унікальний номер (1,2,3,4) навіть якщо значення однакові.RANK(): Може мати пропуски, якщо є однакові значення (1, 2, 2, 4).DENSE_RANK(): Без пропусків (1, 2, 2, 3).LAG() (значення попереднього рядка у вікні), LEAD() (наступне значення). Використовуються для розрахунку приросту (Delta) день-до-дня (MoM, YoY).Партиціонування — це поділ однієї величезної логічної таблиці на дрібніші фізичні шматки (партиції) на жорсткому диску за певним ключем (зазвичай за Датою — Date, Рoком, Місяцем).
Навіщо: Коли ви робите SELECT запит з умовою WHERE created_at = '2023-11-01', база даних використовує Partition Pruning (обрізку партицій). Вона відкидає всі інші місяці та роки і сканує лише один малесенький файл, пришвидшуючи запит у десятки разів порівняно з Full Scan.
Data Lineage (походження даних) — це візуалізація та зберігання інформації про життєвий цикл даних: з якого джерела вони прийшли, через які таблиці й трансформації пройшли та в яких фінальних дашбордах були використані.
Чому важлива: Якщо метрика на дашборді СЕО раптом показує від'ємний прибуток, Data Lineage дозволяє швидко "розмотати" клубок і знайти, на якому етапі (в якому скрипті) закралася помилка. Це економить години на дебагінг.
Інкрементальне завантаження (на відміну від Full Reload) обробляє лише нові або змінені дані. Основні підходи:
updated_at > 'остання_дата'.Якщо бізнес додав нові колонки або змінив тип даних, пайплайн не повинен впасти.
mergeSchema = true під час запису. Якщо з'явилась нова колонка в DataFrame, рушій автоматично змінить DDL таблиці на диску.Це вирішує концепція Slowly Changing Dimensions (SCD):
is_active = True) та маркерами часу valid_from і valid_to. Старий рядок позначається як неактивний.previous_city), куди переходить старе значення, а поточна колонка оновлюється.Дата-каталог — це централізований репозиторій метаданих, що допомагає організаціям структурувати та знаходити свої дані. (Аналог "Google" для внутрішніх даних компанії).
Він автоматично сканує бази даних (Crawling), зберігає схеми таблиць, інформацію про власників таблиць (Data Stewards) та теги. Відомі приклади: Alation, Collibra, AWS Glue Data Catalog, Amundsen.
Це формати відкритих таблиць (Open Table Formats), побудовані поверх Parquet, які приносять властивості ACID баз даних у Data Lake:
MERGE, Time Travel, Schema Evolution.Колонкова БД (OLAP) записує дані на диск не рядками (послідовно кожен запис), а по-колонково. (Всі значення колонки Date лежать підряд на диску, далі йдуть всі значення колонки Price).
Випадки використання: Ідеальні для аналітики, бо при запиті SUM(Price) СУБД читає лише одну конкретну колонку. Рядкові ж БД (Postgres, MySQL) довелося б завантажувати в пам'ять усі стовпчики (Full Scan). Приклади колонкових БД: ClickHouse, Amazon Redshift, Snowflake.
Це два популярних колонкових (Columnar) бінарних формати для зберігання Big Data. На відміну від CSV, вони мають власну схему всередині файлу.
Оскільки зберігати гігабайти "старих" даних щороку стає дуже дорого, дата-інженери використовують Storage Tiers (класи зберігання) у хмарі (наприклад AWS S3):
AWS Glue — це Serverless платформа для інтеграції, обробки (ETL) та каталогізації даних в AWS.
Job Bookmarks (закладки) — це вбудований механізм відстеження стану, який дозволяє інкрементальне завантаження (Incremental ETL).
Після кожного запуску Glue Job зберігає внутрішню позначку "я закінчив роботу ось на цьому файлі" або "ось такий останній timestamp". При наступному запуску Job буде зчитувати тільки нові файли, згенеровані після завершення минулого запуску, ігноруючи старі. Це запобігає дублюванню та економить час/гроші.
Amazon Athena — це Serverless SQL-сервіс для миттєвої аналітики сирих даних прямісінько з об'єктного сховища Amazon S3.
Вона базується на Presto. Не потрібно крутити власні сервери і вантажити дані в базу — ви просто вказуєте SQL-запит до файлу в S3, і він миттєво виконується. Плата знімається лише за 1 Терабайт просканованих даних (близько $5).
AWS Lambda — це FaaS (функції як сервіс). Ви пишете короткий код (Python, Node.js), а AWS запускає його в ізольованому мікро-контейнері ТІЛЬКИ у відповідь на подію (запит до API, поява файлу в S3, тригер CloudWatch).
Обмеження:
/tmp директорія) обмежені кількома ГБ.Amazon RDS (Relational Database Service) — це керований хмарний сервіс реляційних баз даних (PostgreSQL, MySQL, Oracle).
Вам не потрібно власноруч встановлювати ядро БД на сервери. RDS автоматично бере на себе резервне копіювання (Backups), патчі безпеки ОС, мінорині оновлення рушія та надає легку настройку Multi-AZ (гаряча репліка в іншій зоні доступності для миттєвого підняття у разі падіння основної станції).
Маскування даних — це метод приховування чутливої інформації (Personal Identifiable Information – PII, як-от кредитні картки, адреси, номери телефонів).
***-**-2342), залежно від ролі (рівня доступу) юзера, що зробив запит.MPP — це бази даних, що складаються з десятків обчислювальних серверів, які обробляють запити паралельно (напр., Redshift, Teradata).
Завантаження: Ніколи не використовуйте стандартні INSERT INTO для мільйонів рядків, бо воно піде через один вузол-лідер. Завжди використовуйте масові утиліти (наприклад, команду COPY в Redshift для завантаження багатьох файлів із S3 відразу всіма воркерами паралельно).
У класичному розумінні B-Tree індексів (як у Postgres) — рідко, адже вони займають занадто багато місця для Терабайтів і гальмують масовий запис. Натомість використовують:
WHERE x = 5 лежить поза блоком `[10...50]`.Контроль якості (QA) є критичним, щоб BI звіти не обманювали бізнес. Найпопулярніший фреймворк: Great Expectations.
Цей інструмент дозволяє задати "очікування" у вигляді простого тексту або JSON (напр. "значення price має бути більше 0", "колонка email не має бути пустою"). Пайплайн запускає цей тест на свіжому DataFrame; якщо відсоток помилок критичний — завантаження зупиняється намертво (аудит), а дев-команді надсилається алерт.
Черга "мертвих" повідомлень — це патерн архітектури обробки повідомлень.
Якщо ваш Spark Streaming/Kafka пайплайн отримує пошкоджений або некоректний JSON-об'єкт, який не може бути розпарсеним чи обробленим, щоб не "падати" і не зупиняти обробку всього потоку, він "відловлює" цей об'єкт (Exception) і записує його у спеціальну резервну чергу або S3-бакет — DLQ. Там інженери пізніше зможуть проаналізувати поламане повідомлення та повторно завантажити його.
ASG — це можливість хмари автоматично підіймати або видаляти віртуальні сервери (інстанси) залежно від навантаження.
Наприклад, якщо завантаженість процесорів поточних серверів перевищує 80%, ASG автоматично купує і запускає ще два сервери та підключає їх до Load Balancer. Якщо навантаження падає до 20% вночі, ASG "вбиває" зайві сервери, щоб компанія не переплачувала.
WHERE YEAR(date) = 2023 — це погано, ігнорує індекс. Правильно: WHERE date >= '2023-01-01').Ідемпотентність — це властивість процесу (pipeline), коли багаторазовий його запуск з тими ж вхідними параметрами дає один і той же фінальний результат у БД (без дублювання даних).
Вона досягається, наприклад, тим, що на початку скрипта ми виконуємо DELETE FROM tgt WHERE date = 'поточна', а потім INSERT, замість просто виконання "сліпого" інсерту. Або за рахунок UPSERT/MERGE (за первинним ключем), яка при повторному запуску тільки оновлює ті самі рядки значеннями, нічого не ламаючи.
Статичне маскування: Фізичний процес заміни конфіденційних даних у базі даних (наприклад, перед створенням копії для розробників/тестувальників). Оригінальні дані втрачаються назавжди в цій копії.
Динамічне маскування: Справжні дані залишаються в безпеці на диску, але "маскуються" (у вигляді ***-**-253) на льоту під час зчитування інформації базою даних, зважаючи на привілеї чи роль користувача, що робить цей запит (наприклад, касир бачить лише останні 4 цифри картки).
MPP (Massively Parallel Processing) — це архітектура масово-паралельної обробки, де дані та запити розподіляються між кількома незалежними вузлами (нодами).
Головні відмінності:
Лямбда-архітектура — це підхід до обробки даних, розроблений для того, щоб одночасно справлятися як з масовими батч-завантаженнями (batch processing), так і з обробкою потоків у реальному часі (stream processing).
Складається з трьох шарів (компонентів):
Медальна архітектура — це патерн проєктування даних, який використовується для логічної організації даних у Lakehouse (наприклад, в Databricks) для поступового покращення якості даних у міру їх проходження етапами.
Нормалізація — це процес організації структури БД для мінімізації надмірності даних та запобігання аномаліям оновлення/видалення.
Incremental data load (Інкрементальне завантаження) — це процес завантаження в Data Warehouse/Lakehouse лише нових або змінених даних з певного моменту часу, замість повного щоденного перезавантаження (Full Load).
Основні методи:
WHERE updated_at > 'остання_сесія').Для забезпечення безперебійної потокової передачі та Fault Tolerance:
Data Governance (Управління даними) — це набір внутрішніх правил, політик та процедур компанії, що регулює: якість, доступність, безпеку та використання даних.
Ефективні практики реалізації:
Dataset API у Spark побудований на глибокій (compile-time) перевірці типів, яка можлива завдяки строго типізованим мовам (Scala або Java).
Оскільки Python є мовою з динамічною типізацією, він фізично не підтримує жорстку компіляційну перевірку типів. Тому в PySpark всі дані обробляються через DataFrame API (де схема перевіряється в runtime). Імітувати Dataset у Python немає сенсу — він би втратив свою головну перевагу (compile-time type safety) і перетворився б на звичайний DataFrame.
=, <, >, BETWEEN,
IN).=). Дуже швидкий, але зараз
використовується рідше через оптимізації B-Tree.Це гарантії доставки повідомлень у розподілених системах (Kafka, RabbitMQ, SQS):
Звичайний tuple підтримує лише доступ за індексом (напр. t[0]), що погано читається у складних пайплайнах. Для OОП-стилю (доступ як t.name) існують три основні підходи в Python:
__init__, __repr__). За замовчуванням об'єкт можна змінювати (mutable), підтримує Type Hints.Це породжувальні патерни проєктування:
Amazon SQS FIFO гарантує отримання повідомлень "First-In-First-Out" та Exactly-Once Delivery завдяки вбудованому механізму дедуплікації.
Брокери (як стандартний SQS) працюють за принципом At-least-once delivery. Дублікати виникають через проблему "Мережевого розриву" (Network Partition або Timeout):
Якщо консюмер (Worker) прочитав повідомлення, обробив його, але відповідь-підтвердження про успішну обробку (ACK) загубилася під час відправки назад брокеру через збій у мережі, брокер подумає, що Worker вмер (Visibility Timeout expired). Брокер поверне це старе повідомлення назад у чергу, після чого його знову прочитає інший Worker. Саме тому кожен етап вашого пайплайну в Data Engineering має бути ідемпотентним!
Найкраща практика (Best Practice) при переведенні SQL у Spark або Pandas:
.filter() або .where() ще до .join(). Не робіть join гігантських таблиць, якщо вам цікавий лише 1 регіон..select() лише тих колонок, які потрібні для фінального групування, щоб зменшити об'єм пам'яті (RAM), необхідної для Shuffle під час Join.broadcast() хінт у DataFrame API, що повністю усуне повільний Shuffle, оскільки маленька таблиця буде розіслана в RAM кожного воркера.Це вирішується механізмом Consumer Groups (Групи споживачів).
У Apache Kafka, якщо всі ваші мікросервіси/воркери об'єднані однією групою (мають однаковий параметр group.id), Kafka гарантує, що повідомлення з однієї партиції отримає лише один конкретний Consumer з цієї групи.
Якщо ви хочете, щоб це ж повідомлення паралельно обробив зовсім інший застосунок (наприклад, один консюмер пише в БД, а інший шле email), ви повинні дати їм різні імена Consumer Groups.
Data Retention (політика збереження) / TTL (Time To Live) — це правила, що визначають, як довго система повинна фізично зберігати дані, перш ніж вони будуть автоматично і безповоротно видалені, щоб звільнити місце на диску і виконати правила GDPR.
log.retention.hours). Після цього брокер видаляє старі партиції (сегменти), навіть якщо консюмери не встигли їх прочитати.На рівні інженерії даних неякісні дані не повинні блокувати роботу, але й не можуть безконтрольно потрапити в Data Warehouse. Підходи:
expect_column_values_to_not_be_null('user_id').WHERE або JOIN ... ON. Додати складені індекси.Так, може. Існують розподілені NewSQL бази даних (наприклад, Spanner, CockroachDB), які гарантують ACID транзакції і пристроєні для роботи з безліччю вузлів.
Також зараз популярні формати відкритих таблиць над Data Lake — Apache Iceberg, Delta Lake та Hudi. Вони забезпечують ACID транзакції над звичайними Parquet файлами, використовуючи журналювання транзакцій (Transaction Log). Вони дозволяють декільком процесам Spark одночасно записувати і читати файли на AWS S3, уникаючи ситуацій з частковим записом або пошкодженням даних (dirty reads).
Це концепція логічної організації даних у Lakehouse, популяризована компанією Databricks, яка розділяє дані на 3 рівні якості:
Спекулятивне виконання — це конфігурація (spark.speculation=true), спрямована на боротьбу з повільними вузлами (stragglers).
Якщо один чи два Task'и виконуються аномально повільніше від усіх інших (наприклад, через зношений жорсткий диск чи перевантажений процесор на одному з воркерів), Spark "спекулятивно" запускає точнісінько такий самий Task паралельно на іншому, простійному вузлі. Той, хто виконає завдання першим, його результат буде враховано, а повільного "лузера" (straggler) Spark безжально вб'є (kill task).
Масштабування Streaming системи має кілька рівнів:
Blue-Green Deployment — це стратегія випуску нових версій без жодного даунтайму (Zero Downtime).
У вас існують два абсолютно ідентичні виробничі середовища. Blue (Синє) — поточне живе середовище, туди йде весь трафік користувачів. Ви деплоїте нову версію коду в Green (Зелене) середовище, яке поки що ніхто не бачить. Після внутрішнього тестування, ви миттєво перемикаєте балансувальник навантаження (Load Balancer) з Blue на Green.
Якщо в Green виявилася критична помилка — ви так само в один клік повертаєте балансувальник назад на Blue.