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


Автор: Андрей Демидов - lead data engineer.
Связаться: @andrewdemidovv
Download Telegram
Зачем данным инженер?

Есть же аналитики данных и они иногда даже выполняют такие задачи: извлечение данных, подготовка данных, хранение. Но написать скрипт на SQL или запустить парочку работающих ETL - это еще не инжиниринг. 👀

Посмотрим на проблемы с точки зрения бизнеса 💲
Вот что происходит если в работе с данными нет твёрдой инженерной руки:
1) раздутый штат аналитиков - им не хватает времени: трата дорогих ресурсов аналитиков на то, чтобы выполнять требования к данным (а пришли ли данные, а правильно ли они пришли, а везде ли поменяли логику, когда она поменялась, а правильная ли вот эта цифра в отчете и тд.)
2) высокие риски: снижение доверия к данным, на один и тот же вопрос два аналитика дают разный ответ, неконтролируемые изменения, дублирующаяся логика у разных аналитиков, отличающаяся логика для сбора одних и тех же данных.
3) дорогие аналитики - высокая точка входа: каждый должен знать все детали хранения "сырых" данных, детали реализации приложения.

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

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

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

Важен инженерный подход, а не сама роль
Хорошо бы, конечно, держать отдельного человека или даже команду дата инженеров, но если нет под рукой парочки хороших инженеров, то понимание смысла инжиниринга полезно и для аналитиков, особенно тех, которые вынуждены все делать сами - неплохая точка роста на мой взгляд.
👍8
Инженер и данные pinned «Канал про данные как инженерную дисциплину. Архитектура, модели данных и мышление — из практики. Реальные кейсы, принципы, ошибки и выводы из них. 🔵Бизнес-модель данных: технические и бизнес-сущности 🔵Изменения: предвидеть или сделать неважными 🔵Airflow…»
База

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

1️⃣Роли инструментов важнее самих инструментов
Инструментов в дата инжиниринге, да и вообще инжиниринге, создано очень и очень много. Знать все просто невозможно. Лучше знать какие проблемы они решают, то есть понимать место инструментов в архитектуре решения. Например, Apache Airflow - это оркестратор и знание зачем нужен оркестратор и какова его роль важнее самого инструмента или другой пример: брокер сообщений - это база, а apache kafka - инструмент. База данных тоже имеет свою роль, а postgresql, mysql, clickhouse - только инструменты.

2️⃣Архитектурные принципы важнее языков программирования
На меня очень повлияло когда-то изучение принципов SOLID и чистой архитектуры Роберта Мартина. Язык программирования - это деталь реализации. Тем более при растущей эффективности AI.

3️⃣ Проблемы бизнеса важнее приложения/системы
Как работает бизнес лучше спрашивать у бизнеса, а не у разработчиков приложения. Любое приложение - это инструмент, автоматизация, надстройка над бизнесом, которую сделали какие-то разработчики, принимая какие-то технические решения - интерпретация бизнеса. Пользуйтесь первоисточником информации. Лучше изучить бизнес процесс, чем базу данных приложения. Первоисточник важнее интерпретации.

📄 Получилось в стиле agile манифеста
Принципы написаны по формуле важно/важнее, это значит что правая часть утверждений тоже очень важна, но левая важнее.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Данные без модели - деньги на ветер.

Модель данных - ключевое понятие в работе с данными, потому что описывает ключевые для бизнеса сущности, дает им определения, фиксирует взаимосвязи. Любые отчеты, метрики, прогнозы строятся исходя из свойств каких-то сущностей. Модель отвечает на вопросы: Хранилища данных содержат данные о чем? А что такое эта сущность X? А чем характеризуется эта сущность X?

Без модели будет путаница и риск ошибок.

Пример путаницы без модели 1 - отчет без основания. Отчет строится на данных и обычно включает несколько единиц хранения (таблиц или файлов) и если заглянуть "под капот" некоторых отчетов, то там в можно встретить такие названия: dataset_v1, prod_basa, content, final_report - и внутри действительно какие-то смешанные обрывки данных (например в power BI можно посмотреть какие есть таблицы, а в excel/spreadsheets на листы и тд. Откройте свои, если есть. Узнаете свой отчет? 😉). Можно ли тут ответить на вопрос какие данные о каких сущностях использованы в отчете? Легко ли проверить корректные ли в нем данные? Легко ли изменить отчет/добавить данные? Может ли это сделать любой аналитик, без риска, что что-то сломается? Можно ли считать такой отчет надежным? - деньги на ветер

Пример путаницы без модели 2 - присвоение свойств не тем сущностям. Например, у вас интернет магазин и вам важно с какого девайса клиент зашел на ваш сайт и сделал заказ. И вы добавляете свойство device заказу. Но разве заказ имеет свойство device? Это свойство визита/просмотра страницы, который в свою очередь связан с заказом. Проблемы возникают, когда подобное свойство пробрасывается через все сущности (еще хуже, если через несколько приложений), только ради того чтобы сделать некий срез данных в итоге. Это приводит к тому, что нет источника правды, данные дублируются. - деньги на ветер

Пример путаницы без модели 3 - хранилище (DWH) есть, а модели нет. Даже не пытайтесь построить хранилище данных без описанной и задокументированной модели данных. Даже о простых, на первый взгляд, понятиях, например заказ или клиент, могут быть разные мнения у вас, у бизнеса и у того парня (тут еще хорошо бы иметь бизнес процесс, но это другая история). Но и что более важно: а что собственно строим? Как без модели понять что построено то, что нужно? Хранилище данных - продукт, а модель - его описание для потребителей. Первый же потребитель спросит: а что значит заказ здесь? Не согласится с вами и не будет использовать данные - деньги на ветер. Или еще хуже - интерпретирует все это по-своему и примет неверное бизнес решение - большие деньги на ветер.

Ок. Модель важна. Но откуда она берется?

Если говорить кратко, то это продукт эксперта в области бизнеса (доменной области). Заметьте: не аналитика, который "все знает и все отчеты строит", не дата инженера который "красиво собрал dwh" и даже не того разработчика, который "у нас тут все написал". Все они безусловно могут поучаствовать в дискуссии, но окончательное решение все таки за экспертом/лицом принимающим решение/стейкхолдером.
🔥8👍1
Автоматизация и интеграция

⭐️ Делаем свои потоки данных удобными для контроля, развития, изменения.

Сегодня немного порассуждаю о разделении автоматизаций и интеграций.

Если коротко, то автоматизация - это про бизнес логику, а интеграция это про технику. Одна интеграция может использоваться в нескольких автоматизациях и наоборот - одна автоматизация дергать несколько интеграций.
Я заметил что дата инженеры и даже software инженеры склонны смешивать эти понятия как у себя в голове, так и в реализации. Хотя по-моему это разные вещи и стоит их чётко разлелять.
Предположим если вы реализуете задачу типа передай данные во внешний сервис, когда мы закрыли продажу (конверсия). Слово "когда" здесь чёткая граница. То что до - интеграция, а остальное автоматизация.

Разделять это нужно из-за разных причин для изменения (привет принцип S - single responsibility в SOLID). Бизнес логика может меняться так как это угодно бизнесу: правила будут добавляться и изменяться. А вот интеграция изменится только если изменится контракт (api интерфейс например).

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

Если продолжить пример выше, то можно создать класс, предоставляющий интерфейс с методом upload_conversion - это и есть интеграция. А в оркестраторе (например в популярном Airflow) создать DAG, один или несколько, которые будут дергать интерфейс (метод класса) столько раз и в тех местах как нужно - это автоматизация.

#датаинженер
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Про Jupyter Notebook. Нужен дата инженеру?

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

Сейчас я бы хотел поделиться своим мнением о пайтон блокнотах. Это удобный интерфейс для работы с пайтон скриптами. Можно запускать код частями, перезапускать отдельные части, выводить результаты и тд. Есть разные способы работы с ними: jupyter, vscode, google colab и другие. Вы найдёте множество хвалебных отзывов этому инструменту в сети, а я хотел бы поговорить о том, когда его использование вредно.

Можно выделить 3 применения блокнотов: анализ данных, разработка потока данных (инжиниринг), обучение.

📎 Анализ данных
Здесь все ок. Это именно то, почему блокноты популярны. Если бы я делал классификацию инструментов для работы с данными, то поставил бы пайтон блокноты в один ряд с инструментами анализа и визуализации такими как Power BI или Tableau. Смысл ведь тот же. Да и порядок работы тоже: подключился к источнику, взял данные, объединил, трансформировал, сделал отчет с графиками и таблицами.
Вывод - использовать ✔️

📎 Разработка и инжиниринг
Вот тут обратная сторона популярности. Аналитики или инженеры начинают писать в блокноте логику потока данных (ETL процесса), получают какой-то скрипт и запускают его периодически, чтобы получить данные в каком-то целевом месте назначения (база данных ил файл). Проблема в том что скрипт - это такой монолит кода, который работает только здесь и сейчас. Любое его изменение дорого и рискованно. Когда скриптов много, даже у одного аналитика, неизбежно будет дублирование кода и логики. Изменение одного правила требует пересмотра множества скриптов, при этом в каждом из них еще несколько мест, которые тоже надо поправить, все эти места нужно найти и не забыть. По этой причине на практике, когда используют скрипты, они становятся личными - конкретный аналитик его написал и вроде понимает, как и что и может что-то поменять пока помнит, другой аналитик даже не лезет туда. И даже если вроде удалось внести изменения можно ли гарантировать, что результат скрипта соответствует требованиям и изменение правила для колонки А не повлияло на качество данных в колонке Б? Нельзя. Логика не изолирована. Соответственно за этим следует полная проверка качества (QA).
Обманчивая простота ведет к огромным затратам на поддержку.
Еще один поинт сюда: согласитесь будет странно, удивительно и даже смешно, если бэкенд разработчик вдруг возьмет пайтон блокнот и напишет в нем REST API для приложения. Кажется очевидным, что так делать никто не будет. Так почему тогда разработчик ETL должен наступить на эти грабли?
Вывод - не использовать ❌

📎 Обучение или черновик
Блокноты удобны для обучения, так как можно легко запускать или перезапускать отдельные части кода, или как черновик, когда разработчик не уверен в том, что делает и хочет видеть результат каждого блока кода. Но это формирует вредную привычку. Я рекомендую для инженерных задач сразу отказаться от блокнотов и использовать инструмент для дебага с точками останова (есть в каждой IDE, например в Pycharm), которые позволяют увидеть состояние в некоторой точке процесса.
Вывод - можно, но не рекомендую ❗️

Пайтон блокноты полезны, если правильно использовать.
Для анализа данных? Берем!
Для инжиниринга? Спасибо, не надо.

#датаинженер
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8👎2
Офисный вайб после трех лет удаленки

Так получилось, что прошлые два года я работал только удаленно, а еще за два года перед этим работал в офисе суммарно месяца три. И вот месяц назад я приехал в город Кишинев и начал работать в офисе. Могу точно сказать, что получил заряд энергии от личного общения с коллегами. 🔋
Хотя конечно офисы бывают разные и важна атмосфера, которую компания поддерживает в офисе. Мне повезло! У нас в офисе приятный творческий вайб: когда прийти и когда уйти - твое личное дело дело твоей команды, есть бар, где можно бесплатно выпить лимонад со льдом, но больше всего заряжает когда CEO утром встречает счастливый с широкой улыбкой и чуть ли не обнимает тебя так, как будто именно ты принес компании прибыль в этом месяце 😁

На фото стикеры, которые лежат в офисе и любой их может брать. Именно они добили меня до написания этого поста. Люблю такие мелочи! ☺️
❤8
Airflow только оркестратор

Airflow очень популярный инструмент для управления ETL процессами. Я буду часто упоминать его, потому что он достаточно прост для начала работы и достаточно интересен для построения правильных потоков данных. Сегодня я хотел бы немного поговорить о его роли.

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

📄 Функция оркестратора запускать операции в заданной последовательности по расписанию.

И эта последовательность в Airflow называется DAG (Directed Acyclic Graph).

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

Если все сделано правильно можно:
🔸 Запустить логику без запуска airflow
🔸Переиспользовать эти независимые функции в других процессах (дагах)
🔸Написать тесты для логики
🔸Независимо менять логику отдельных частей процесса

И все это еще и укладывается в solid принципы как я люблю ☝️
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤2
Падает процесс, не хватает ресурсов. Давай увеличим ресурсы!

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

📝 Обычно это примерно такой кейс: в etl происходит несколько запросов к каким-то базам, которые вытаскивают данные за сутки, потом это все объединяется, есть какая-то логика для фильтрации и агрегации и затем это все должно быть загружено в целевую базу. И тут два варианта: 1) на каком-то из этапов данные не влазят в память (например, воркера в airflow/виртуальной машины/вашего личного пк) и таким образом разработчик приходит к выводу, что надо увеличить ресурсы. 2) запрашиваемые данные не влазят в память источника и тут разработчик думает, что надо увеличить ресурсы там.

💔 Во-первых это подмена проблемы решением (есть такая ошибка в решении проблем). Проблема здесь: количество ресурсов для выполнения превышает доступное количество ресурсов. Такая постановка проблемы заставляет подумать не только о том, что ресурсов мало, а ещё и о том что потребление ресурсов большое.

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

1️⃣ Почему выбран для одновременной обработки именно тот период, который выбран? Есть ли причина на то, что данные должны быть обработаны одновременно?

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

Самое простое тут разбить обработку по периодом, то есть просто настроить расписание оркестратора на выполнение процесса чаще, например раз в час или два.

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

2️⃣ Есть ли в данных колонка/ключ/дименшн, который позволит сделать срезы и выделить независимые данные? Например это может быть project, store, product, tenant, type, region и тд.

Это снова про уменьшение совместно обрабатываемого объема данных. Вы уже догадались: разделяем весь объем на несколько срезов и обрабатываем отдельно.

3️⃣ Для обработки ресурсов хватает, а вот источник не может вернуть данные, потому что у него ответ не влазит в память или он ушел в таймаут?

Тут можно разделить один запрос на несколько, потом собрать ответы вместе и обработать совместно. Несколько последовательных запросов выполнять долго? Сделай асинхронные запросы.

4️⃣ Простые решения не подходят?

Тогда уже стоит подумать об увеличении ресурсов.

А если увеличивать некуда/слишком дорого? Подумать о применении big data инструментов для распределенной обработки или real time процессах. Тут важно именно хорошо подумать, потому что это резко усложняет ваш стек и инфраструктуру. Не стоит внедрять новые инструменты без веской причины.

©️Вообще обычно такие проблемы решаются по п 1 или п 2, иногда по п 3.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤1
Неточные данные! Смотреть нельзя!

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

Перфекционистам дальше не читать 😁

Мне вспомнилась шутка про часы:
- Какие часы лучше: те что стоят или те что отстают?
- Те что стоят, так как показывают точное время два раза в сутки.


Я думаю, что все сводится к тому что считать "точными" данными. Здесь я немного порассуждаю.
Данные лишь отражают реальный мир. В той степени, которая нам нужна для принятия решений. При этом данные собираются какими-то способом: может руками, а может техническими устройствами (в широком смысле). Любой способ имеет свою точность или погрешность. Способов со 100% точностью просто не существует. Лучший в мире датчик давления, который, например, поставят на ракету для отправки в космос будет иметь точность 0,999999. При этом чем точнее способ, тем он дороже. Любые IT системы, на данные которых мы смотрим, тоже имеют некоторую гарантированную точность, имеют контракт. Потери данных, искажения данных возможны всегда.

Такие рассуждения подводят к выводу, что мы всегда работаем с некоторой неточностью, которая нас устраивает. Это значит что точность не должна быть максимальной, она должна быть необходимой и достаточной. Точность - это бизнес требование к системе. Я пишу системе, потому что невозможно от DWH требовать точность выше, чем она есть у источника данных. Система может обеспечить точность, которую обеспечит "худший" участник. Когда мы работаем с данными мы стремимся не ухудшать уже имеющуюся точность, но к сожалению иногда приходится делать допущения при обработке данных или добавлять сложную логику обработки, увеличивая риск ошибки...

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

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

🕒 Продолжая шутку с часами.
Если заиграться в перфекционизм, то получите часы, которые показывает точное время два раза в сутки. Лучше дайте мне часы которые постоянно показывают "неправильное" время, но с отклонением не более 10 минут, тогда придя на встречу я либо успею попить кофе, либо извинюсь за опоздание, либо приду на 20 минут раньше, если встреча важная. То есть смогу принять решение. 👌
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤2
Про точность. Часть 2.

Продолжение предыдущего поста

Спроси у бизнеса какую точность он желает и он ответит: конечно 100% 😁
Потом будут переговоры про то, что это дорого и долго и вы сойдетесь что, например 95% - ок, то есть это та точность, которая устроит бизнес и которую можно обеспечить при приемлимых для бизнеса затратах ресурсов.

Кстати по моему личному опыту 95% действительно ок, дальше ресурсы для уточнения растут в геометрической прогрессии и улетают в космос.

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

Планируем работу
Полезно ставить требования точности еще и чтобы знать, что команда инженеров тратит время на важные вещи. Если кто-то пришёл и сказал вот тут у вас ошибка в данных, не нужно все бросать и бежать исправлять (разве что у вас инженеры без дела сидят). Измерьте количество случаев и их влияние на точность. Если это снижает точность ниже уровня - берём в работу, если нет, отправляем в бэклог. Да, может оказаться что накопленные проблемы приведут к общему снижению точности, тогда берём в работу то что влияет сильнее или сделать проще 😉
Я видел не раз, как прибегает кто-то и с видом что все пропало объясняет, что срочно нужно проверить/исправить/пересчитать, а на вопрос сколько таких случаев, ответ: 1 с начала года на 100500 заказов. 😐 успокаеваем его, даём водички, заносим проблему в бэклог и пьём кофе работаем дальше.
👍6
Лидерство. Мои провалы

Я был лидом несколько раз в разное время и каждый раз с перерывом на пару лет. И вот я снова стал лидером маленькой, но мощной команды дата инженеров и решил поделиться своей рефлексией по моему прошлому опыту. Расскажу о своих версиях лидерства по порядку их внедрения 😊

Версия 1. Вы не должны думать, а просто делать что говорят.
Эта установка мне казалась логичной. Я думал так: Руководству нравится как я работаю, но я не успеваю делать все, поэтому они хотят меня масштабировать, то есть сделать так, чтобы "копии" меня делали больше. Из этого я делал вывод что мои люди должны меня чётко повторять, то есть думать они не должны, думать буду я, а они просто руки. Очевидно, что работать в таких условиях ребятам было тяжело мягко говоря. Но осознал я это позже, уже после того как ушёл из той компании.

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

Общее у версий 1 и 2 то, что я не видел людей, а видел только задачи и знания.

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

Ключевое отличие версии 3 в установке: я должен, вместо вы должны.

Я только недавно снова стал лидом и пока ещё не откатал версию 3 😊 надеюсь на этот раз пройдёт лучше чем в первых двух.
❤7
Кейс с TEMP TABLE

Кейс скорее про разовую ручную проверку данных, чем про потоки данных.

📄 Предположим у нас есть какой-то процесс, который должен делать записи в базе данных при наступлении каких-то условий. Это может быть бизнес логика или реакция на события другого приложения или интеграция. Каждая такая запись имеет в данных идентификатор связанной сущности, а сущность эта вообще в другой базе (или вообще у партнера). У нас есть список идентификаторов сущностей, по которым должны быть записи, и вот мы хотим узнать для каких именно сущностей НЕ была создана запись.

©️Вот конкретный кейс: приложение отправляет событие в event stream (например kafka), когда создается sale. К event stream подключен Clickhouse как Event storage, который читает и сохраняет события. Мы знаем, что по какой-то причине не была отправлена часть событий (мониторинг есть). У нас есть список sale id (например 2-5К), и мы хотим узнать по каким именно из них не были отправлены события, то есть получить список идентификаторов.

💬 Звучит просто на первый взгляд. Нам нужно сравнить два списка: список сущностей, со списком событий. Но сложность в том, что списка сущностей нет в базе. Тут может прийти мысль написать скрипт на пайтон и сравнить списки, но мы сделаем проще и быстрее - используем Temp table.

Temp table - существует в рамках сессии и автоматически удаляется при завершении сессии.

Создаем пустую табличку (синтаксис clickhouse, в postgresql тоже самое только вместо TEMPORARY используется TEMP)
CREATE TEMPORARY TABLE IF NOT EXISTS sales (
sale_id int
)

Вставляем значения из предварительно подготовленной переменной. Так как это разовая задача создаем переменную ручками из списка сущностей приведя к виду (1), (2), (3).
INSERT INTO sales VALUES :sales

Проверим. Должен быть весь ваш список
SELECT * FROM sales

И теперь мы можем сделать запрос, который вернет только те id, по которым события нет. Тут могут быть разные варианты с подзапросом и join. Например так.
SELECT *
FROM sales
WHERE sale_id not in (
SELECT sale_id
FROM events
WHERE type = 'some/event/type'
)

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

©️TEMP TABLE удобная штука, если нужно быстро что-то исследовать не делая выгрузки, трансферы, дополнительные скрипты.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍2
Псевдокод - прием инженера.

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

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

💬 А продумывать помогает очень простой и удобный прием - псевдокод.

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

❗️Не путать с докстринг (docstrings). Докситринг для клиентов метода/класса - описание как использовать метод и для чего он нужен. А псевдокод для разработчиков - отражает конкретные действия в коде, то есть то как именно выполняется задача.

Вот пример псевдокода в методе класса на пайтоне. Хотя можно использовать везде и в sql запросах тоже.
   def set_lead_id(self, *, crm_uri, calls_storage_uri):
"""
Performs actions to enrich calls data by lead_id and project_key
"""
# pseudocode
# Option 1:
# group calls in the same time range
# (half an hour) in order to reduce count of requests to crm
# reduce calls by caller number
# execute as many requests to crm as groups passing time range and phone. get lead_id, project.
# assign lead_id and project to every call in the initial calls list matching by phone.
# The assumption: all calls with the same phone number within a half an hour will have the same lead_id
# Option 2:
# get calls without lead within time range
# prepare request for every call with time range as call datetime +/- 2 minutes
# combine requests with UNION clause
# execute combined request to crm. get lead_id, project.
# push data to calls table

# Use option 2
# дальше пишем код, используя вариант 2


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

Псевдокод позволяет:
🔸продумать цепочку действий от начала до конца не отвлекаясь на синтаксис языка
🔸увидеть логические противоречия до того как вы уже написали половину кода.
🔸увидеть допущения и спорные моменты, которые были не очевидны
🔸увидеть плюсы и минусы разных вариантов, оценить их потенциальное быстродейтсвие, выбрать лучший
🔸делегировать написание самого кода кому-то (так еще не пробовал, но идея хорошая. Сюда же входит использование AI. А что? Чем псевдокод не промпт для chat gpt? 🤔)

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

Так и получилось в моем недавнем кейсе. Метод стал медленно работать. Я прочитал псевдокод, понял работу метода, понял в каком месте есть потенциальная проблема, затем внес изменения сначала в псевдокод, убедился что логически это будет работать, затем легко нашел нужное место в коде и быстро внес изменения. Готово! 5 минут потратил, закрыл и забыл еще на месяц, на полгода или больше, пока логика снова не поменяется. 🙌

‼️И еще помните! Комментарий, который не соответствует коду хуже, чем отсутствующий комментарий.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍4
“Правильность” данных

Осторожно! Душный пост! 🧐

Я заметил, что в общении с коллегами часто использую словосочетание - консистентность данных. Обычно все это понимают как некая “правильность” данных и в общем-то так и есть, но нам как инженерам, ответственным за эту правильность, стоит задуматься над тем что это такое. ☝️

Можно найти по этой теме с десяток понятий в разных публикациях типа consistency, integrity, quality, correctness, validity и тд. Определения этих понятий смешаны: где-то используются как синонимы, где-то имеют отдельные смыслы. И я вряд ли могу внести тут полную ясность, но свое мнение в общую массу мнений закину 😁

Я бы выделил как минимум согласованность (consistency) и целостность (integrity).

📝 Согласованность - состояние, при котором все копии данных одинаковы во всех связанных приложениях, базах данных и тд. (сайт IBM).
Для дата инженера это значит, что данные в хранилище (DWH или Data mart) или в отчёте не должны противоречить источникам данных.

🔖 Организовывая трансфер данных и выполняя трансформации, дата инженер должен быть аккуратен и безпристрастен. Есть риск увлечься! Нельзя допустить вольных изменений для красоты или для соответствия чьим-то личным ожиданиям и тд. Все операции в коде должны быть подкреплены бизнес логикой или логикой трансформации, то есть по каждой строчке можно обоснованно ответить на вопрос “почему так?”

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

📝 Целостность - состояние, при котором данные записаны именно в том виде, в котором было задумано. (В википедии неплохо написано). Такое определение очень широкое. С точки зрения дата инженера то, как “задумано” - это модель данных. То есть данные целостносты, когда они соответствуют модели данных (пост данные без модели - деньги на ветер).

🔖 Тут у меня хорошие новости. 😋 Соответствие модели можно и нужно гарантировать технически! Модель можно превратить в набор правил/требований к сущностям, к их свойствам, их типам, обязательности, наличии связей между сущностями и тд.

🤔 Подумаем про контроль. С архитектурный точки зрения должен быть некий “участник”, который возьмёт на себя эту функцию и ответственность гарантировать соответствие модели или целостность. Это может быть приложение, сервис, микросервис, непосредственно база данных, какой-то подключаемый инструмент и тд. Тут главное сделать так, чтобы был только один ответственный - одно место в архитектуре, которое держит необходимую для этого логику.

©️Держа в уме согласованность с источниками и технически гарантируя соответствие данных модели, вы предоставите бизнесу достаточно “правильные” данные. 🙌 Хотя это конечно не все...
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍4
Сюрпризы от базы данных приложения

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

Функция базы данных приложения - поддерживать работу приложения.

Схема в ней оптимизирована именно для этой задачи. В ней созданы те или иные таблицы только для того чтобы выполнять нужные задачи. В таких базах обычно дохрена таблиц с множеством связей в основном технических - нормализация для скорости CRUD операций 🚀. Данные одной бизнес сущности могут быть размазаны по множеству таблиц или же наоборот несколько бизнес понятий "впихнули" в одну таблицу. И все это нормально, потому что, повторюсь, это операционная база, а не аналитическая. Поэтому база данных приложения плохой источник правды для бизнеса и поэтому существуют ETL процессы с необходимой T - трансформацией.

Трансформация - изменение модели данных. В данном случае из модели базы данных приложения в модель бизнес сущностей.

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

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

Приложение может удалять записи, описывающие бизнес сущность и пересоздавать их снова, правильно, с генерированием нового идентификатора. Ключевой момент здесь: с точки зрения бизнеса сущность та же! Просто приложению в каком-то сценарии было проще удалить запись и создать новую. То есть запись в базе данных новая, а бизнес сущность та же. Для приложения это норм, а вот для нашей аналитической базы возникают проблемы при наследовании идентификаторов из операционной базы. Мы уже не можем полагаться на такие идентификаторы и должны все усложнять выбирая другой уникальный ключ для связи.🥲
👍4🔥2
Кайфанул от PostgreSQL Extensions

Я - сижу и читаю что-то в телефоне с довольным видом и издаю звуки удивления или восхищения.
Жена - Что читаешь?
Я - про PostgreSQL extensions. 😁

Тут я ловлю себя на мысли, что реально кайфанул от возможностей, которые дают расширения 😄

Читал я вот эту статью. В начале автор пишет:

Расширения PostgreSQL - это лучшая часть PostgreSQL. Они добавляют функционал в вашу базу данных, изменяя и улучшая выполнение процессов.

Дальше в статье перечислены некоторые расширения с примерами. Мне особенно понравились вот эти
🔸 pg_stat_statements - отслеживает статистику запросов выполняемых базой данных. Дает детальную информацию о плане выполнения. Поможет дебажить запросы, выявлять медленные запросы.
🔸 pg_partman - помогает управлять партициями. Пожалуй самое известное расширение.
🔸 postgres_fdw - позволяет настроить прокси подключение к другой PostgreSQL базе и запрашивать данные из нее так как будто эти данные лежат тут же в обычной таблице.

©️Я со своей командой сейчас активно строим DWH на PostgreSQL и мы обязательно попробуем эти и другие расширения.👍
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍3
600К баксов в год дата инженеру

Сегодня попалось видео с коротким интервью Zach Wilson.
Этот парень считается крутым дата профессионалом в сообществе. Впервые я увидел его контент на LinkedIn. Если на LinkedIn начать интересоваться постами о дата инжиниринге, то 100 пудов наткнешься на его профиль.

В этом видео меня зацепили пара моментов. И я решил с вами поделиться.

1️⃣ Во первых конечно - 600К в год! Это он получал, работая в Airbnb (ушёл оттуда год назад и создал свой продукт). Меня впечатлило само число‼️(для особо дотошных после уплаты налогов это примерно 450К. я загуглил 😉) Я конечно знал что могут платить много, но я думал ну 250К ребята в США получают, а тут вот. При этом он сказал что это норма, что его коллеги получали не меньше.

2️⃣ Второе - это его мнение про базовые знания дата инженера. Тут конечно нужно учитывать, что интервью было короткое и ответ был тоже короткий, но тем не менее он назвал вот что:
🔸языки - SQL, Python (scala, rust полезно, но не те как первые два)
🔸оркестрация - Airflow и добавил что в общем-то оркестрация в целом.
🔸 Spark - по его мнению он станет ещё более популярным чем сейчас
🔸Моделирование данных. Тут он сказал, что даже некоторые ребята, которые получают 500К, делают это хреново 😄

Заметьте тут нет упоминаний модных сейчас слов типа lakehouse, apache iceberg или snowflake или hive, hadoop и тд. Наверняка все это важно, но менее важно, чем пункты выше. В этом смысле мое мнение близко к его. Разве что, пожалуй, Spark в этом коротком списке я не ожидал увидеть. Отмечу ещё, что чуть позже в другом контексте он упоминал Data Mesh и Master Data Management. Возьмем на заметку ☝️

©️Так что ребята нам ещё есть ого-го куда расти 📈 💲
❓Что думаете про его мнение о базовых знаниях?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🤔3❤2
Лучший ETL тот, которого нет

Такой “идеальный” ETL процесс можно получить используя postgres_fdw - расширение PostgreSQL (пост).

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

При этом:
1️⃣ Данные не копируются. Когда пользователь выполняет запрос, та часть запроса, которая относится к внешним таблицам, “пробрасывается” в другую базу. Можно так работать как с DQL (select) так и с DML (insert, update, delete)
2️⃣Можно выбрать таблицы, к которым подключаться.
3️⃣Настройка расширения необходима только на стороне запрашивающей базы данных. Для базы данных-источника все выглядит как обычные запросы, она и не знает что вы какое-то хитрое соединение настроили.
4️⃣Множество баз может быть подключено к одной основной базе.

При использовании fwd (foreign data wrapper) создаются внешние таблицы (foreign table). Такие таблицы отлично заменяют ETL процесс или трансфер данных, в котором нет трансформации (как бы EL процесс без T - трансформации) 😉. Другими словами, когда вы извлекаете данные откуда-то и загружаете куда-то “как есть”, можно просто использовать внешние таблицы с postgres_fdw и получить плюшки:
✔️ Гарантия согласованности (пост). Никакого физического процесса перекладывания данных нет, все успешно завершенные операции с данными в базе-источнике тут же доступны через базу, которая подключена через внешние таблицы. Это даже круче чем real-time.
✔️ Все обработки, трансформации, вычисляемые колонки (measures, metrics) и другие манипуляции с данными выполняются в одном месте - в основной базе, которая является источником для других.
✔️ Отсутствие лишнего ETL процесса, который нужно поддерживать, который потребляет ресурсы и тд.
✔️ Нет необходимости в бэкфиле данных в случае изменений в основной базе источнике

Есть и минусы конечно.🫣
🔵Вся вычислительная нагрузка ложится на основную базу. Если это проблема, можно рассмотреть репликацию. Мы пока что наблюдаем.
🔵Данные каждый раз проходят по сети между базами. Это не проблема, если базы у вас в одном месте (например в одном кубернетес кластере или в одном регионе AWS и тд). В других случаях есть риск недоступности из-за проблем с сетью, но это в общем-то касается любых способов как ETL, так и репликации.

Сама техническая реализация супер простая.

-- устанавливаем расширение
CREATE EXTENSION postgres_fdw;


-- создаем подключение к базе-источнику.
-- Этот шаг выполняется только один раз и в дальнейшем
-- может использоваться для добавления таблиц
CREATE SERVER dwh
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (dbname 'dwh', host 'your-host.rds.amazonaws.com', port '5432');


-- ваша база ходит к базе источнику с запросами и поэтому ей нужны креды
-- можно настроить для каждого пользователя индивидуально (для роли кстати нельзя)
-- или указать PUBLIC - все пользователи вашей базы будут обращаться ко внешним таблицам используя указанные креды
CREATE USER MAPPING FOR PUBLIC
SERVER dwh
OPTIONS (user 'data_mart', password '');
-- ВАЖНО! Создайте юзера с read only правами, чтобы избежать неожиданностей, когда кто-то сделает вам Insert, Update, Delete в вашей основной базе


-- создаем внешние таблицы, выбирая какие именно таблицы хотим из внешней базы и куда именно их определить в вашей
-- убрать limit to, чтобы забрать всю схему
IMPORT FOREIGN SCHEMA "foreign_schema_name" limit to (table1, table2)
FROM SERVER dwh INTO local_schema_name;


©️Благодаря postgres_fdw мы отключили сразу ряд ETL процессов (дагов в Airflow)

➡️ PS. У Postgres есть и другие fwd (foreign data wrapper) для такого же хитрого подключения почти к любым источникам. Я видел, что есть к MySQL и к AWS S3 например 👍.
У нас в инфраструктуре есть mysql базы у приложений и я думаю мы ещё попробуем часть данных использовать оттуда без копирования🙌.
А возможность так подключаться к Aws s3 - это же вообще пушка! Это же получается Postgres можно использовать как вычислительный движок, физически разделив вычисление и хранение (архитектурный паттерн: separate compute and storage), но это уже другая история.🤓
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7🤨1
Логи! Если хочешь потратить время

Иногда у инженеров или аналитиков возникает идея извлечь полезные данные из логов. Иногда даже разработчики приложений сами говорят нам: ну вот же логи! там есть данные.

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

Логи существуют для дебага работы приложения. Реже для целей мониторинга и алертов.
Таким образом, логи - технические данные для разработчиков и причины их изменения могут быть самые непредсказуемые.
На логи:
❌НЕ пишут бизнес требования
❌НЕ пишут документацию
❌НЕ делают контракты на пейлоад
❌НЕ проверяют качество и не тестируют.

а если все это делают то это уже не логи

Туда разве что для ресерча можно залезть👀 (хотя для ресерча все можно) и то я бы полез туда только в крайнем случае: оставим дебаг тому кто это наделал разработчикам приложений.

©️Извлечение аналитических данных из логов - ступенька вниз к хаосу или шаг в болото - пока по колено зашел вроде ниче, а чуть расслабился и затянуло с головой и тратишь все свое время на поддержку
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Особенности foreign data wrapper

Ранее я писал о плюсах использования внешних таблиц, теперь хочу написать об особенностях, которые в нашем use case приводят к проблемам. Спойлер: мы отказались от использования внешних таблиц.🙁

У foreign data wrapper есть особенность:
Fdw запрашивает фул таблицу с удалённого сервера, даже если вы применили фильтры в запросе.😮 Очевидно, что если внешняя таблица на миллионы строк, то ждать придётся очень долго пока вы получите всю таблицу. Эту особенность можно обойти, если “помочь” fdw понять как правильно подготовить запрос ко внешней таблице. Вот здесь хорошо описано и приведены способы написания запроса оптимального для внешних таблиц.🙌 Поэтому я назвал это особенностью. Сама по себе особенность не проблема, работать можно.☝️

А проблема обусловлена именно нашим кейсом.👀

📝 Ситуация (Кейс):
У нас есть DWH на Postgresql и есть Data Marts тоже на Postgresql. Дата марты содержат сабсеты данных специфические для какой-то задачи/домена/департамента. В тех случаях, когда данные в дата марте полностью совпадают с данными в двх как раз возникает отличная возможность избавиться от лишних ETL процессов. Тут то мы и применили внешние таблицы.
В нашем кейсе дата март - конечный продукт для пользователей. Туда приходят делать запросы для анализа, ресерча, построения отчётов и тд. Дата март как продукт должен предоставить возможность работать с данными, делать простые или сложные запросы, оптимальные или неоптимальные.

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

📝 Решение:
Физическое хранение данных в самом дата март. Мы перешли к плану Б и настроили логическую репликацию на те таблицы, схема которых совпадает в двх и дата март, то есть там же где были внешние таблицы. 🙌

©️Но мы не убираем foreign data wrapper “на помойку”! В других кейсах, где такими внешними таблицам будут пользоваться инженеры можно работать эффективно. Так что отложили пока в сторонку.
Кстати mysql_fdw тоже попробовал и он тоже отлично работает и настраивается так же легко как и postgres_fdw.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5