How Rapport Labs Adopted StarRocks for Ad Performance Data
Rapport Labs рассказали, как перестроили систему аналитики рекламных кампаний после того, как MySQL-based pipeline перестал масштабироваться.
Изначально события хранились в двух MySQL-таблицах:
• ad_interaction_raw содержала показы, клики и другие пользовательские события, записываемые в реальном времени;
• ad_purchase_aggregated_events содержала покупки, связанные с рекламными показами или кликами, и обновлялась раз в пять минут.
Периодический batch job считывал новые строки по ID из global_pointer, агрегировал impressions, clicks, billed amount, purchase quantity и purchase amount по рекламной кампании, а затем публиковал инкременты в Kafka.
Kafka consumer обновлял агрегированные таблицы в MySQL и пересчитывал CTR, CVR и ROAS.
Campaign ID использовался как partition key, а transactional inbox pattern обеспечивал идемпотентность обработки.
Вначале архитектура работала нормально.
Проблемы появились, когда количество рекламных показов стало приближаться к 10 миллионам в день.
Каждый новый уровень агрегации требовал отдельного batch job, Kafka consumer и MySQL-таблицы.
В результате:
• росло количество дублирующихся пайплайнов;
• увеличивалась write-нагрузка на MySQL;
• cursor-based обработка могла приводить к пропускам данных;
• изменения исторических данных не попадали в агрегаты автоматически;
Высокая нагрузка на MySQL была критична: та же база участвовала в формировании billing source data, поэтому задержки могли влиять на рекламную выручку.
Команда решила вынести обработку performance data в отдельную OLAP-систему и сравнила BigQuery, ClickHouse и StarRocks.
BigQuery уже использовался внутри компании, но не подошел для частых near-real-time запросов: on-demand pricing становился дорогим, а capacity-based модель требовала постоянно держать избыточные ресурсы.
При тестировании ClickHouse команда столкнулась с проблемами интеграции с Glue Catalog и Iceberg.
Таблицы с timestamp-колонками не появлялись в SHOW TABLES, а SQL-запросы через Glue Catalog завершались ошибкой S3 URI.
StarRocks выбрали по нескольким причинам:
• стабильная интеграция с Glue и Iceberg;
• возможность читать source data напрямую из S3 без повторной загрузки;
• Data Cache для кэширования удаленных блоков на BE-узлах;
• Materialized Views для предварительной агрегации часто запрашиваемых данных;
• Cost-Based Optimizer для выполнения JOIN;
• совместимость с MySQL wire protocol, позволившая переиспользовать существующие драйверы и query libraries backend-приложения.
Source of truth при этом оставили вне StarRocks: данные хранятся в Apache Iceberg на Amazon S3, а метаданные — в AWS Glue Catalog.
StarRocks читает исходные Iceberg-таблицы как external tables, но данные, которые непосредственно выдаются продавцам, формируются во внутренних Materialized Views.
Сначала кластер развернули в shared-data конфигурации с FE и stateless CN.
В этой архитектуре внутренние таблицы и MV также хранились в S3.
Для near-real-time аналитики Materialized Views обновлялись каждые несколько минут.
Это генерировало большое количество S3 PutObject и привело к более высоким расходам, чем ожидалось.
После перехода на shared-nothing архитектуру с FE и BE внутренние данные и Materialized Views стали храниться на локальных дисках BE-узлов.
Связанные с этой частью инфраструктуры расходы снизились примерно на 95%, а мониторинг refresh Materialized Views стал проще.
Поскольку исходные данные оставались в Iceberg, для миграции команде не пришлось переносить source data: они развернули новый кластер и заново построили Materialized Views.
В результате Rapport Labs получили масштабируемую систему near-real-time агрегации, снизили нагрузку на MySQL, устранили пропуски в агрегатах и сократили восстановление после инцидентов с более чем четырех часов до менее чем 30 минут.
Этот кейс хорошо показывает архитектуру, в которой Iceberg используется как независимый storage layer и source of truth, а StarRocks — как OLAP-движок и serving layer для пользовательской аналитики.
@tldr_data