Инженер и данные
721 subscribers
39 photos
30 links
Канал про инженерный подход к работе с данными


Автор: Андрей Демидов - lead data engineer.
Связаться: @andrewdemidovv
Download Telegram
Clean code в Airflow. Контекст

Продолжаем делать код в Airflow красивее и чище 😉

Работа с контекстом - ещё один очень простой способ снизить зависимость логики от оркестрации и на шаг приблизиться к Clean code.

Airflow создаёт контекст при каждом запуске дага. Этот контекст содержит ряд аргументов, которые могут передаваться оператору. Это по сути key-value пары или в случае python - dict. Оператор может использовать их для рендеринга темплейтов или в качестве аргументов функций. Вот как раз про передачу контекста как аргументов в функции я и хочу написать в этом посте.

📝 Если в двух словах — передавай контекст, принимай аргументы☝️. Код становится более читаемым и главное чистым, когда вместо kwargs принимаются конкретные аргументы.

Вот пример при работе с датами (пост про даты) и не только.

from airflow import DAG
from airflow.operators.python import PythonOperator
from datetime import datetime


def extract_data(
data_interval_start: datetime, # забираем из контекста только то, что нужно
data_interval_end: datetime, # типизация поможет IDE найти проблемы в коде
project: str = None, # опциональный параметр
**kwargs # поможет игнорировать лишние аргументы из контекста
# особенно полезно, если функция используется в нескольких дагах
)-> list[dict]:
data = []
return data


with DAG(
dag_id='example_use_context_dag',
start_date=datetime(2025, 1, 1),
schedule_interval=None,
catchup=False,
) as dag:

task_extract_data = PythonOperator(
task_id='extract_data',
python_callable=extract_data, # контекст передается всегда, то есть никакие действия не нужны
)

task_extract_data2 = PythonOperator(
task_id='extract_data2',
python_callable=extract_data,
op_kwargs={
'project': 'the_best_of_the_best', # можно добавить любые аргументы
},
)


Как видите не нужно как-либо явно передавать аргументы, которые уже в контексте. Они только и ждут, чтобы их красиво принимали🤤. Опять же отмечу, что, пожалуй, самый важный эффект здесь — снижение зависимости функции от оркестратора: функция явно принимает всё необходимое для работы. Как бонус — это удобно при работе в IDE: теперь IDE может анализировать код и подсвечивать проблемы, особенно если вы укажете типы.😎

В документации airflow есть полный список переменных контекста. Они их назвали почему-то переменными темплейтов (шаблонов), как будто ограничивая возможности их применения только теплейтами 🤔. Им следовало назвать их переменными контекста. забыли у меня спросить 😁

Вот ссылки на другие посты о Clean Code в Airflow
1) передача результата между тасками и свойство output
2) lambda в таске
3) про работу с датами
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9
Про что одна строка?

📝 Пожалуй самый первый, главный вопрос при работе с любым набором данных (датасетом, дата мартом (витриной), таблицей) - про что одна строка?

На самом деле это вопрос моделирования, но даже обычный разовый отчёт имеет свою модель.☝️

При этом неважно, говорим мы про подготовку данных или анализ — без понимания единицы (minimum grain) невозможно работать. Поэтому это первое, что нужно для себя прояснить, даже если заказчик не может ответить на вопрос прямо. 💡
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤3💯3
Язык данных = бизнес язык

📝 Если бизнес использует какие-то понятия или свойства, добавьте их в модель явно.

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

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

Пример
На мите вы слышите от бизнеса такую фразу:
лиды, которые позвонили нам по общую линию, могут иметь разное намерение (купить или получить поддержу), которое еще должно быть подтверждено.

В одной фразе заключена ценнейшая информация о бизнес модели! 👀 Есть сущность лид. Лид имеет свойство источник, свойство намерение, и свойство-флаг подтверждено ли намерение. Вот что должно быть в данных! Определения этих понятий, конечно, следует уточнить и в идеале записать в документ. Этот документ и есть бизнес модель данных. Не путать с табличками в базе данных приложения.
Как правило, в базе данных приложения техническая модель: лид создан через API, звонок был на какой-то номер, плюс некоторые признаки намерения и его подтверждения, которые ещё нужно правильно интерпретировать, то есть трансформировать.

Или вот бытовой пример. Бизнес просит посчитать бананы, а в базе приложения у вас только желтые объекты продолговатой формы.😁 Вот и назовите их в модели явно бананами и убедитесь, что точно отделили их от кукурузы.🙌

©️Задача инженера перевести данные с технического языка на бизнес язык.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥6❤5
Такие разные select запросы & трансформации

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

Select запросы к данным бывают разные: с трансформацией и без.
Для ответа на вопросы (отчеты) трансформаций быть не должно!

Вот признаки трансформации в селекте:
🔵 Применение логики/правил, видно по использованию if, case, coalesce и других условных операторов.
🔵 GROUP BY используется для дедупликации, а не для агрегации.
🔵 WHERE используется для исключения некорректных данных, а не для выборки.
🔵 Есть подзапросы. Любые. Там, где JOIN, или там, где колонки, или через CTE (WITH) — неважно.
🔵 Изменение значений. Например, назначение имен идентификаторам статусов или переименование текстовых значений.
🔵 Расчёты и формулы.
🔵 Использование оператора LIKE.

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

Тут вы можете справедливо заметить, что бывают новые запросы, к которым данные ещё не готовы, или проверки гипотез. И то, и другое, конечно, потребует трансформаций в запросах, но это по сути — ресерч, проверка и подготовка нужной логики, и затем принятый вариант всё равно должен быть автоматизирован и превращён в витрину: это гарантирует, что трансформация всегда выполняется в одном месте и один раз, и любые изменения наследуются всеми зависимыми моделями.🙌 Кроме того логика трансформации может быть вынесена за пределы sql и выполнена на python, в spark и тд. А витрина может быть опубликована через API. Суть от этого не меняется. ☝️

Кстати, пример с API даже более наглядный в этом смысле: ведь чтобы дать доступ к данным через API, вы вынуждены подготовить всё заранее, чтобы пользователь просто пришёл и забрал как есть, с какими-то минимальными возможностями фильтрации (даже агрегации обычно там нет).

💡 Если для регулярных отчетов требуется трансформация - делайте витрину. Если есть более одной витрины с похожей логикой трансформации - пересмотрите модель данных.

©️не все select запросы одинаковы по смыслу. Для предсказуемых ответов на вопросы Select должны быть без трансформаций 👌
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
Correlation vs causation

Это труба погнулась, потому что села чайка? Или чайка села именно на место сгиба уже после того, как труба была согнута?

В этом случае ответ, конечно, очевиден. Но эта картинка отлично подчёркивает саму идею:

📝 то, что выглядит на первый
взгляд
как причинно-следственная связь, может оказаться простым совпадением или следствием какой-то иной, настоящей причины.

Об этом стоит помнить при решении проблем. Особенно при траблшутинге (это когда что-то не работает, и срочно нужно сделать так, чтобы работало😁).

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

Такие картинки кстати здорово всплывают в памяти в нужный момент и помогают посмотреть на ситуацию под другим углом. Наверное, поэтому они и называются мемами (на самом деле все сложнее и интереснее, спросите у gpt откуда слово meme). Так и я год назад увидел эту чайку, и теперь каждый раз её вспоминаю, когда нужно разобраться, что пошло не так - correlation vs causation. 🤔 Надеюсь и вам пригодится.

©️В целом этот пост снова про мышление инженера/аналитика. Посмотреть под разными углами, допустить неочевидное, усомниться в том, что бросается в глаза. 🧐
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤4😁2🤯1
Channel photo updated
Meta data или данные о данных

✏️ Meta data - это данные о данных. То есть это информация именно о самой записи, о строке: откуда она взялась, кто записал, когда создана запись, когда изменена и многое другое.

Это важно знать и записывать, чтобы иметь больше контроля над данными, чтобы знать больше деталей о конкретно этой записи (строке) в этой таблице. Иметь её "паспорт". 💪

На практике это просто дополнительные колонки в той же таблице. Ну или если у вас json, то дополнительный meta объект внутри. При этом их стоит явно отделить от данных, например используя префикс. Мы вот используем meta_.

Еще раз подчеркну, что важно не путать мета данные и данные!
Вот несколько примеров, объясняющих суть различия:

🔵 заказ создан 1 мая 21:00, а запись в DWH о нем создана 1 мая 22:35 (потому что у вас периодический батч процесс), created_at заказа будет отличаться от meta_created_at. А если потом уже внутри DWH на основе таблицы заказов будет обновлен дата март, то там опять же будет свое meta значение, например 22:45. Дата создания заказа не меняется, а вот дата создания записи о заказе в той или иной таблице будет своя.

🔵 Еще более наглядный пример при бэкфиле. Заказ создан в приложении 1 мая 2025 года. По какой-то причине данные о нем собраны вчера - 2 июня 2025. Важно знать, что эта запись была создана только вчера, и что отчеты построенные, например, 1 июня еще ничего о нем не знали! ☝️

🔵и ещё пример. вы сохраняете run id - идентификатор процесса, в рамках которого создана/изменены строка. Это поможет, например, при траблшутинге, так как вы точно знаете какие данные затронул тот самый ран.

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

Я даже думаю, что если у вас еще нет мета колонок в данных и вы считаете, что они вам не нужны, то просто вы еще не созрели 😁 Вы почуствуете этот момент, когда они вам понадобятся. Даже если вы просто собираете отчёт, стоит как минимум знать дату последнего обновления строки, которую вы взяли в отчёт.🫣

Минимальный набор по-моему должен включать две колонки:
©️meta_created_at
©️meta_updated_at
Я бы прям рекомендовал вставлять их во все таблицы. Для зависимых (downstream) процессов необходимо знать именно изменённые записи и meta_updated_at будет как раз кстати.👍

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

📎 Если есть записи из разных источников:
🔵meta_source
🔵meta_source_object_type
🔵meta_source_object_id

📎Об оркестраторе:
🔵meta_orchestrator_run_id
🔵meta_orchestrator_run_timestamp

📎 Хранилище:
🔵meta_created_at
🔵meta_updated_at

Плюс если храним историю изменений:
🔵meta_is_current
🔵meta_valid_from
🔵meta_valid_to
🔵meta_version_hash
🔵meta_version_number
🔵meta_version

Я напишу на эту тему ещё пару постов, например чуть подробнее напишу про meta_updated_at 🙌 так что продолжение следует... 😊
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥3✍1
Meta данные - meta_updated_at. Часть 1

В прошлом посте писал о мета данных в целом, а в этом двойном посте остановлюсь на реализации одного из самых важных мета свойств - таймштамп последнего изменения. ☝️

Будет длинный двойной пост.
Конечно, я мог бы просто написать как мы делаем, но так неинтересно, по крайней мере мне самому 😁 я напишу почему именно так. Спойлер: во второй части будет код функциии на postgresql 👍

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

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

Для начала нужно решить кто ответственен за эту свойство. У нас есть три (как минимум) участника, через "руки" которых проходят данные и которые могут добавить свой мета след:
🔵источник
🔵исполнитель (оркестратор)
🔵хранилище.

Порассуждаем: чтобы сказать изменится ли что-то, нужно знать в каком состоянии это что-то сейчас.

Источник ничего не знает о том, в каком состоянии сейчас запись в месте назначения, более того он вообще не знает о существовании этого самого места назначения. Есть соблазн в момент извлечения данных добавить прям в select что-то вроде now или current timestamp, но это будет время извлечения, а не каждое извлечение = изменение!

Примерно по той же причине этого не может знать и исполнитель (оркестратор). Он может только знать о времени обработки, что опять же не тоже самое, что время изменения.

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

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

Вторая часть поста⬇️
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤3
Meta данные - meta_updated_at. Часть 2

(сначала смотри два предыдущих поста ⬆️)

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

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

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

Вот наша:

CREATE OR REPLACE FUNCTION set_meta_updated_at()
RETURNS TRIGGER AS $$
DECLARE
old_jsonb jsonb;
new_jsonb jsonb;
BEGIN
-- Convert rows to jsonb and remove metadata fields
old_jsonb := to_jsonb(OLD) - 'meta_updated_at' - 'meta_created_at';
new_jsonb := to_jsonb(NEW) - 'meta_updated_at' - 'meta_created_at';

-- Compare entire row contents
IF old_jsonb IS DISTINCT FROM new_jsonb THEN
NEW.meta_updated_at := CURRENT_TIMESTAMP;
RETURN NEW; -- proceed with update
END IF;

RETURN NULL; -- no changes → cancel the update
END;
$$ LANGUAGE plpgsql;


А сам тригер - обычный вызов этой функции, поэтому его приводить здесь я не буду.

Результат:
1️⃣ Покрыты ВСЕ способы апдейта строки. Невозможно выполнить update, не запустив тригер. Это техническая гарантия, что meta_updated_at всегда обновится. То есть неважно, как и кто обновляет данные: батч процесс, реалтайм запись, руками через консоль - тригер всегда запустится и всегда поставит таймштамп, ЕСЛИ что-то изменилось.
2️⃣ Обновление meta_updated_at в одной транзакции с самой операцией update. Это тоже техническая гарантия, что если что-то идет не так, то транзакция целиком не будет принята: нет изменений нет и нового таймштампа.
3️⃣ Нет лишних dead tuples. Это особенности именно postgresql.

В двух словах про dead tuples: update строки приводит под капотом к созданию новой версии строки, а старая удаляется позже только при уборке - vacuum. То есть, по умолчанию postgresql не проверяет есть ли по факту отличия, и если 1000 раз запустить операцию update с одними и теми же данными на одну и ту же строку, postgresql создаст 1000 версий под капотом. Все они займут место на диске, создадут запись в лог, нагрузят диск операцией записи, нагрузят cpu чтобы все это провернуть.

Так вот функция в тригере отменяет update, если понимает, что изменений нет. Возврат null в коде выше как раз для этого. Нет новой версии -> нет dead tuple -> нет дополнительной нагрузки.
4️⃣ Быстро настроить для любой таблицы. Все очень просто. Одна функция на всю базу! В любой таблице создал колонку и создал тригер. Готово!
Более того, всё это можно обернуть в скрипт, и одним движением руки вы раскатаете решение на всю базу или всю схему. Мы так и сделали 😊

✏️Минус. (или нет)
Каждая операция update запускает функцию. Внутри функции какие-то операции, а выполняет операции cpu. Следовательно, появляется дополнительная нагрузку на cpu. Однако это сглаживается тем, что я писал выше про dead tuples. Справедливости ради скажу, что у нас нагрузка на cpu слегка выросла после введения этих тригеров, но скорость увеличилась из-за меньшего количества операций с диском. 👌

©️Очень простой способ получить мета колонку с таймштампом последнего изменения, да еще и с гарантией на техническом уровне. 🙌
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥3👏1
Изменения: предвидеть vs сделать так, чтобы они были неважны

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

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

Проблема в том, что вопрос поставлен так, что решения нет.

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

Неопределенность всегда существует. Даже если вам кажется, что вы все продумали. Просто не нужно ее бояться. Пытаться все продумать наперед = бояться. Лучше принять ее и быть готовым к тому, что изменения будут. 🥲

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

❌Предвидеть - создать решение, подходящее заранее предусмотренным изменениям.

✔️Сделать так, чтобы было неважно - создать решение, которое легко адаптировать при любом изменении.

✳️есть еще третий вариант, но он немного офтоп для этого поста. Сделать так, чтобы не жалко было сломать и выкинуть - fail fast. Это тоже интересный вариант для случаев, когда неопределенность на другом уровне - под сомнением сама необходимость решения проблемы или даже само ее существование. Однако это другая история

📎Правильная постановка вопроса:
Как сделать решение, которое легко адаптировать/расширять в случае изменений?

Это запускает мышление в другую сторону.

©️Я думаю, что создание технического решения, которое легко расширять, дополнять, легко понять - один из ключевых принципов инжиниринга. Работающий код ещё не значит хороший. Хороший код определяется НЕ сколько тем как он работает, а тем, как легко его изменять.

Эта финальная мысль мне напомнила книгу Роберта Мартина Clean architecture, которая несколько лет назад дала мне ответы на многие вопросы 😉
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7
Квантовая аналитика 😄

Такой перл у нас родился сегодня на дейлике 😆

А тема вообще очень серьёзная. И это я не про квантовую физику😁.

Auditability - полная прослеживаемость и проверяемость данных: почему, в какой момент менялись. И как следствие этого свойства — возможность получить данные на определённый момент времени.

©️Чтобы получать предсказуемые отчеты, а не квантовую аналитику, всегда собираем историю изменений и метаданные 🙌
Please open Telegram to view this post
VIEW IN TELEGRAM
😁6👍5
Без паники!

Пост про траблшутинг и проблем солвинг.

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

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

Вот что поможет избежать паники:
1️⃣ Доверяй себе — если исходить из того, что вы хороший инженер и просто так на удачу ничего не релизите, то значит, вы всё сделали правильно.
2️⃣ Доверяй коллеге — это следующий шаг от доверия себе — он/она тоже хороший инженер и т. д.

Так что вместо того, чтобы сразу по умолчанию признавать всю работу некачественной, стоит потратить немного времени на поиск причины.

Несколько возможных сценариев:

©️ Причина может вообще не быть связана с последними изменениями непосредственно (см. пост). Например, кто-то где-то что-то поменял и то, что вы сделали релиз - просто совпадение.

©️ Причина может быть связана косвенно: изменения выявили скрытую проблему в другом месте.

©️ Причина в небольшой ошибке в релизе - баг.

©️ Причина в критической ошибке в релизе.

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

Берите пример с кота на картинке: без паники! ❤️
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👏2
Сфотал недавно на одном ларьке.

Эта картинка почему-то напомнила мне документацию.

Любую.

К чему бы это.🤔😁
😁13👍2
Google, heavy is the crown?

Раньше я думал, что гугл это идеал, если бы это был человек, то у него был бы нимб или корона. Но поработав с сервисами гугла, я понял, что ничего там особенного:
🔸ошибки (да, я и 503 видел от одного из их сервисов в течение нескольких часов😳),
🔸странное поведение,
🔸запутанная и где-то неполная документация

Все как у людей. 😁 То же самое могу сказать и про facebook, bing и ещё ряд разных не таких известных сервисов. Google — просто яркий пример, чтобы донести саму идею.

Я осознал что все это просто сервисы, написанные простыми разработчиками, которые не факт, что умнее меня или вас. 🧐 (Дисклеймер: я сейчас не имею ввиду топ инженеров того же гугла, которые меняют мир, я имею ввиду ребят, которые работают "в поле" и каждый день пишут код)

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

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

❌Опасно! Есть риск уйти в крайность и стать вечно ворчащим разработчиком, который ругает всё, кроме того, что сделал сам! 🙅‍♂

©️Я разработчик ©️ Я могу ошибаться ©️ Все сделали люди ©️Они такие же разработчики как я ©️Они могут ошибаться 🙌
Please open Telegram to view this post
VIEW IN TELEGRAM
👏6
Дата инженерная доля

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

Ошибки, неточности могут быть в любом сервисе, с которым мы интегрируемся. Но это не всё...

📖 Проблемное поведение сервисов, приложений, источников данных:

🔸Ошибки - сервис не выполняет предъявляемые ему требования

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

🔸Неполные данные - сервис выполняет все известные требования, но в данных не хватает деталей, однако сервис не может добавить эти детали в принципе. Например, есть три внешних сервиса, выполняющие одинаковую функцию. Сервис 1 предоставляет свойства A, B, C; сервис 2 - тоже A, B, C; сервис 3 только A, B.

🔸Нестабильный источник - сервис и требования выполняет и данные полные, но... периодически может быть недоступен.

🔸Разные комбинации всего этого одновременно в рамках одного сервиса

А теперь самое интересное.
Бизнес требует полные, точные данные без ошибок и стабильно.😐


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

➡️ Ошибки? Ну вы же их видите - добавьте в код костыль, фильтраните, пока мы делаем фикс.
➡️ Ошибку исправили. В исторических данных она осталась? Конечно, как мы в прошлом ошибку исправим. Проблема была такая-то - исторические данные исправьте сами.
➡️ Неточности? Да, знаем — добавьте логику на своём уровне, пока у нас руки не дошли туда (никогда не дойдут).
➡️ Неполные данные? Заполните. Сделайте допущение, мы и правила вам расскажем. Примерно.
➡️ Нестабильный источник? Ну есть же второй еще. Берите из него, если первый недоступен, да смотрите, чтобы дублей не было.

⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️

Бизнес:
- В общем сделайте так, чтобы данные отвечали на наши вопросы.
Дата инженеры:
- ок


Такая вот дата инженерная доля. 🥲🫡
Please open Telegram to view this post
VIEW IN TELEGRAM
🫡9👨‍💻3
Data Maturity Levels

Прошлый пост получился немного грустный. Дата инженерная доля... 🫡

✅ То, какая она эта доля у дата-инженера зависит от уровня зрелости компании в отношении работы с данными - Data Maturity Level.

Мне очень нравится модель зрелости, предложенная в книге Fundamentals of Data Engineering. И я хочу привести её в этом посте в сокращенном виде ✏️

Важный момент! уровень зрелости не зависит от возраста компании: компания, существующая полгода, может быть более зрелой, чем компания, существующая много лет. ☝️

1️⃣ Starting with data
Архитектура и инфраструктура данных находятся на начальных стадиях планирования и разработки. (дополнение от меня: Если какие-то инструменты и сервисы и внедрены, то разрознены)
Уровень внедрения и использования данных низкий.
Практическое понимание ценности данных невелико, но стремление к этому есть.
Отчеты и аналитика не имеют формализованной структуры, а большинство запросов к данным выполняется в режиме ad hoc.
На этом этапе дата-инженер обычно выступает как универсальный специалист и берет на себя сразу несколько ролей, например, аналитика или разработчика. Цель дата-инженера — двигаться быстро, добиться первых результатов и принести пользу. Задача здесь - заложить прочный фундамент для работы с данными.

2️⃣ Scaling with data
Компания уходит от разовых запросов к данным и формирует формальные практики работы с ними. Теперь главная задача — создание масштабируемой архитектуры данных и подготовка к будущему, в котором компания действительно будет управляться на основе данных. Роль дата-инженеров постепенно переходит от универсального специалиста к фокусированию на определённых аспектах жизненного цикла работы с данными.
Основным узким местом масштабирования является не число узлов в кластере, не хранилище и не сама технология, а команда дата-инженеров. Нужно делать ставку на решения, которые просто внедрять и поддерживать, чтобы увеличить пропускную способность команды. Внедрять DevOps и DataOps практики.
При этом важно общаться с другими командами о практической пользе данных, обучать организацию тому, как использовать и извлекать ценность из данных (дополнение от меня: правильно использовать).

3️⃣ Leading with data
На этом этапе компания уже действительно управляется данными. Автоматизированные пайплайны и системы, созданные дата-инженерами, позволяют сотрудникам самостоятельно выполнять аналитику и использовать ML. Подключение новых источников данных происходит бесшовно, и из данных извлекается реальная ценность. Дата-инженеры внедряют необходимые механизмы контроля и практики, чтобы данные всегда были доступны людям и системам: governance, catalog, lineage, metadata management, etc.
Дата-инженер на этот этапе может уделять много времени разработке кастомных инструментов и систем, которые используют данные как конкурентное преимущество. Однако здесь возникает соблазн браться за дорогие «хобби-проекты», которые не приносят ценности бизнесу.
Серьёзную угрозу представляет самоуспокоенность. Достигнув третьего уровня зрелости, организации должны постоянно уделять внимание поддержке и улучшению процессов, иначе есть риск отката на более низкий уровень.


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

Вообще всегда, конечно, нужно стремиться к совершенству. Если ваша компания на уровне 1, это не значит, что можно опустить руки типа подождем. Единственный способ попасть на уровень 3 - стремиться к нему. 🚀

А ещё, по-моему, такого чистого разделения на этапы в реальном мире не существует: всегда будут признаки разных уровней одновременно, особенно в рамках целой компании. Наверное уровень можно примерно определить по правилу большинства признаков. Я бы сказал, что мы год-полтора назад были в большей степени на уровне 1, а сейчас основной массой перевалили на уровень 2, и, хотя кое-где нога застряла еще на 1, смотрим на уровень 3. 🫣😋

На каком уровне ваша компания? ⬇️
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Data Maturity Level. Опрос.

На каком уровне зрелости в отношении работы с данными ваша компания? Или проект, если компания слишком большая, и вы не знакомы со всеми практиками.
Anonymous Poll
33%
Starting with data
45%
Scaling with data
22%
Leading with data (data driven)
Профессиональная независимость

* это я сфотал картину Tennis Player в музее Современного искусства в Мюнхене.

Я занимаюсь большим теннисом с тренером. Как любитель. 😎 Иногда мы разговариваем с ним о его тренерской жизни, и однажды он поделился со мной интересной мыслью об отношениях тренер<>спортсмен которую, если подумать, можно распространить и на отношения сотрудник<>компания.

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

Дальше примерно его мысль: ⬇️

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

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

©️Перейдем на отношения компания<>сотрудник.
В этой аналогии сотрудник - это тренер/исполнитель, а компания - спортсмен/клиент.

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

Дисклеймер: Я не предлагаю работать на нескольких работах одновременно или идти во фриланс. Речь о майндсете.

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

©️Хороший тренер специалист всегда найдет работу 😉 💯
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10❤2👍1💯1
Грузоперевозки данных

У AWS еще недавно была услуга по трансферу данных... на грузовике. 😳

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

В прошлом году AWS все таки отказались от этой услуги именно в виде грузовика и теперь предлагают только "небольшие" контейнеры с SSD на сотни TB. (AWS Snowball)

Бизнес-смысл услуги физического трансфера данных очень прост. Например используют для миграции в cloud. Представьте, что у вас свой дата-центр, где вы нажили непосильным трудом петабайты данных. 1 PB данных при скорости 1 Gbps передавался бы около 100 дней непрерывно. А тут AWS как раз со своими грузовиками или контейнерами поменьше... 😁

Вот такой big data transfer. 💪

PS. Вы заметили, что слово snow часто фигурирует в названии дата инструментов? 🤔
👍9😁8❤2🔥1
Настоящий детектив.
Основано на реальных событиях.

Очень интересная история приключилась в нашем офисе на днях.

Хитрость, бдительность, находчивость, арест. В жанре драма, криминал, комедия 😁

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

Полчаса шло это "собеседование", пока полиция не приехала и не арестовала наивного. Оказалось, что он уже три месяца был в розыске за кражу на сумму более 10К евро из разных офисов. Но потом вошёл не в ту дверь... 🙌

Из офисного чата: 😂
🤣17🏆4❤1