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


Автор: Андрей Демидов - lead data engineer.
Связаться: @andrewdemidovv
Download Telegram
Нужно ли хранить историю на уровне моделей?

Часто это воспринимается как дефолт:
делаем модель → сразу закладываем версионирование, SCD, valid_from / valid_to.

Но вопрос — действительно ли это всегда нужно?
История, конечно, важна.
Но важно разделить уровни.

👍 На уровне ingestion layer — да.
Сырые данные, события, изменения в источнике — это базовый слой, который должен сохранять полную историю и не зависеть от дальнейшей логики.

🤔 На уровне model layer всё менее однозначно.
Изменения там обычно происходят по двум причинам:
🔹меняются данные в источнике
🔹меняется логика трансформации

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

Во всех остальных случаях это скорее техническая страховка.

Частый аргумент — observability:
нужно иметь возможность разобраться, почему раньше считалось иначе.
Но для этого не обязательно хранить историю в моделях. Observability можно обеспечить имея:
🔵полная история на ingestion layer
🔵воспроизводимые (детерминированные) трансформации

Что значит детерминированность?
В общем смысле это "один и тот же input всегда ведёт к одному и тому же output". В случае sql трансформаций input это и сам запрос и данные, к которым он обращается.
Если:
🔹 данные на ingestion layer неизменяемы и имеют временную ось (meta timeline)
🔹 функции/запросы имеют свою историю изменений (хотя бы git)

то в любой момент времени можно восстановить нужный input и получить тот же самый output.

Это и есть детерминированный пайплайн.

Тогда:

история в ingestion layer + воспроизводимая логика = возможность восстановить результат на любой момент 🙌


©️Можно не хранить все промежуточные состояния моделей, но при этом уметь получить любое из них при необходимости.

И тогда вопрос сводится к простому:

история в model layer — это осознанное бизнес-требование
или компенсация недостаточной воспроизводимости пайплайна?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤2
Искажение модели

Иногда мы принимаем за бизнес-модель то, что ей не является.

Организационная структура — один из частых источников искажения модели данных.

❗️Элементы оргструктуры начинают определять сущности, метрики, сегментации.

❗️Бизнес-определения начинают разъезжаться —
не потому что меняется бизнес,
а потому что разные отделы «так видят».

❗️Границы ответственности превращаются в границы данных.

И со временем это начинает выглядеть как естественная часть модели.

Например.

Одна команда назовёт запросы клиентов case, другая — lead.
Какая разница с точки зрения бизнеса, если и то и другое — запрос клиента?

Это искажение.

Или маркетинг разделён на направления:
реклама, партнёры, органика, email.

Это нормальное управленческое решение —
разделить ответственность и сфокусировать команды.

Но дальше каждое направление начинает выстраивать свою картину:
свои метрики, свои воронки, свои правила атрибуции.

И постепенно это выглядит так,
будто это разные части бизнеса.

Хотя это один поток:
трафик → клиенты → выручка.

Границы, введённые для удобства управления,
начинают восприниматься как ограничения самой модели.

Искажение.

Со временем это закрепляется в данных, отчётах и процессах.
И начинает влиять на решения.

Что с этим делать

При моделировании важно абстрагироваться от команд, отделов и ролей.
Полезные вопросы:
🔵Эта сущность будет существовать, если завтра отдел расформируют?
🔵 Как изменится сегментация, если завтра два отдела объединят в один?

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

©️В корректной модели оргструктура — это отдельный слой, который дополняет бизнес-объекты, а не подменяет их.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4❤‍🔥1🔥1💯1
Полезный ресурс про то, что происходит в мире ai. Не только про код, а вообще. Вот ссылка на сайт, но у них ещё есть newsletter. Не реклама. У ребят 700 тысяч подписчиков и им реклама у меня точно не нужна 😂

Я читаю у них далеко не все, но чтобы оставаться в теме, по-моему, посматривать стоит.

Например, в последнем посте есть ссылка на репозиторий со скилами. Выглядит интересно 👍 я вот еще в использование скилов не погружался. Завтра попробую.
🔥4
Нужно запретить сортировку в дата-инжиниринге на законодательном уровне.

* так пошутил инженер из Databricks, объясняя работу Spark. Он показал, что сортировка увеличивает потребление ресурсов и время выполнения задачи в несколько раз. Мне понравилась эта цитата, потому что я пришел ровно к тому же выводу работая с Clickhouse. В итоге пришлось изменить свои привычки, наработанные в строковых базах.

©️Большая часть сортировок в запросах существует не потому, что она нужна задаче. Она существует потому, что мы привыкли писать SQL определённым образом. Проблема справедлива для разных систем, но особенно хорошо видна на примере Clickhouse.

▫️Привычка первая — одна строка на ключ.
Если вы много работали с PostgreSQL, рука сама тянется к distinct on или похожим конструкциям. И там это работает хорошо. ClickHouse тоже поддерживает и distinct on и limit 1 by, но они требуют сортировку. Забавно, что AI-ассистенты тоже любят такие конструкции и регулярно предлагают их как решение по умолчанию.
Я тоже использовал такие конструкции, пока не начал регулярно сталкиваться с ростом потребления памяти и периодическими падениями запросов.
В итоге везде заменил их на GROUP BY с агрегатными функциями вроде argMax() и argMin(). Агрегация - вообще любимая операция Clickhouse.

▫️Привычка вторая — посмотреть последние данные через
select * from table order by timestamp (да, некоторые даже не пишут limit полагаясь на IDE, которая получит ограниченное количество строк).
На практике человеку обычно нужно не 100 самых последних строк во всей таблице, а просто посмотреть свежие данные. То есть точная сортировка не является частью задачи, а скорее привычкой. Фильтр по последнему часу плюс limit решают это за доли секунды без сортировки вообще. Пока писал этот пост, прогнал пару запросов на одной из наших таблиц в Clickhouse на 300М записей:
✔️фильтр + лимит - 800 мс
❌сортировка + лимит - 9 минут!

Теперь я стал смотреть критически на сортировку везде. И нашёл order by в пайплайнах, где он просто стоит как артефакт после чьей-то работы. Никто не убрал, а база честно сортирует данные при каждом запуске. И если для строковой базы это терпимо, то для колончатой или для распределенных вычислений (типа Spark) - это выстрел в ногу.

©️Перед тем как написать ORDER BY — убедитесь, что не нарушаете закон. ☝️😁
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤2🔥2
Когда в последний день перед отпуском пытаешься доделать всё😁
😁12❤1
Асимметрия обратной связи

На днях поймал себя на мысли.

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

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

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

У разработчика сайта есть понятные метрики. Он знает, сколько пользователей пришло, сколько оформили заказ, сколько людей дошли до оплаты.

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

А когда результат твоей работы — данные, всё становится иначе.

Мы предоставляем данные как продукт. Дальше пользователь сам формулирует вопрос, анализирует информацию и принимает решение.

Но мы почти никогда не видим результат этой цепочки.

Мы не знаем,
– сколько вопросов сегодня было решено благодаря данным.
– сколько бизнес-проблем удалось обнаружить.
– сколько решений приняли руководители.
– сколько возможностей для бизнеса нашли.

Зато есть другая сторона.

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

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

Но почти никто не приходит сказать:

«Сегодня снова работал с отчетами. Получил ответы на все вопросы. Всё было как нужно.»

Получается интересная особенность профессии.

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

Возможно, именно асимметрия обратной связи и создает психологическую нагрузку.
💯4👍3🤔3😁1🤝1
Языки программирования были нужны только человеку?

Мне пришла одна мысль и я попытался ее развить и порассуждать.

Что, если стек абстракций — от языков программирования до фреймворков — появился прежде всего как интерфейс для человека? Тогда что произойдёт с ним, если новым пользователем вычислительной техники становится AI?

Если оглянуться назад, развитие информационных технологий почти всегда шло через добавление слоёв абстракции:
железо → операционные системы → низкоуровневые языки → высокоуровневые языки → фреймворки → no code / serverless

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

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

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

По сути, языки программирования — это интерфейс. Не для машины, а для человека. А теперь появляется новый «пользователь» — AI. И у него нет наших ограничений: ему несложно держать в голове детали, он не устаёт от низкоуровневой работы, ему не нужно упрощать задачу. Значит, абстракции, созданные для человека, ему не нужны?

Можно представить сценарий, где AI постепенно снимает уровни. Сначала работает через привычные нам языки, потом опускается ниже — туда, где меньше ограничений и больше контроля. Он может работать с промежуточными представлениями, машинным кодом или другими внутренними формами.

Например, подумаем о компилируемых языках. Они же для человека: человек пишет код, а компилятор переводит его из формата, удобного человеку, в формат, удобный машине. Если человека в процессе нет, всё может быть наоборот. AI может работать с представлением, удобным машине, а если человеку понадобится посмотреть на результат — «компилировать» его обратно в естественный язык. Получается своеобразная обратная компиляция: не человек пишет код и переводит его для машины, а машина формирует решение в удобном для себя представлении и при необходимости переводит его обратно для человека

Другой пример. Meta выпустила LLM Compiler — модель, обученную на LLVM IR и ассемблерном коде для задач оптимизации. LLVM IR — это промежуточное представление кода, расположенное ниже привычных высокоуровневых языков программирования.
То есть инженеры в этом случае уже пришли к тому, что "наши" языки программирования только помешают AI.


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

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

Первые могут оказаться временными. Вторые, вероятно, останутся с нами гораздо дольше.

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

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

Кстати в гипотезу из предыдущего поста укладывается аналогия с ремеслами, которые сейчас стали историей.

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

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

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

Хотя у этой же аналогии есть интересное следствие. Кузнецы ведь не исчезли. Они просто перестали быть массовым способом производства. Возможно, останутся и разработчики эксклюзивного software ручной работы.
👍5
Модель космического масштаба

Select count(*)
From solar_system.planets
-- 2005: 9
-- 2006: 8

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

Возникла неопределённость, которую решили на уровне семантической модели — изменили определение планеты, приняли единое формальное определение. Однако Плутон перестал соответствовать определению и перестал быть планетой. Официальное решение IAU 2006 года: Definition of a Planet⁠

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

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

Изменение определения коснулось множества downstream процессов, но это не аргумент против уточнения модели.

По-моему, эта история - хороший пример управления семантической моделью на доменном уровне.
❤3🔥2
Инкрементальное обновление данных в dbt + ClickHouse

Я некоторое время экспериментировал с разными способами обновления моделей в связке dbt + ClickHouse.

Целью было найти хороший баланс между нагрузкой, простотой реализации и консистентностью данных.

Full refresh остаётся самым простым и надёжным вариантом — пока пересчитывать весь dataset не становится слишком дорого. Дальше появляется довольно много вариантов, каждый со своими компромиссами.

Собрал их в небольшой cheat sheet:

— какие стратегии доступны;
— где появляется duplicate или missing-data window;
— что происходит с late enrichment и corrections;
— как отличаются dbt runtime и ClickHouse-native orchestration.

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

Подробности экспериментов и выводы разберу отдельно.
❤9👍3