Apache Superset — востребованное open-source решение для анализа данных, которое можно быстро установить и встроить в существующий технологический стек компании, благодаря большому количеству коннекторов и видов визуализаций. Однако для высоконагруженных систем и сложных сценариев некоторые компании дорабатывают исходную версию — например, внедряют инструменты автоматического кеширования и оптимизируют архитектуру хранения данных для построения графиков. По этому пути в своё время пошли и мы в VK.

Привет, Хабр. Меня зовут Никита Романов. Я руководитель команды разработки аналитических инструментов в VK. В этой статье расскажу о нашем опыте оптимизации Apache Superset под свои задачи.

Про BI в VK

Мы в VK применяем Data-driven подход, то есть принимаем решения на основе анализа данных и фактов. Аналитика позволяет нам отслеживать состояние процессов, оптимизировать продукты и сервисы, управлять рисками и безопасностью, улучшать пользовательский опыт и не только. 

Мы развиваем BI в VK — и расскажем о нескольких трендах этого направления. 

Тренд № 1. Единый BI

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

Поэтому в рамках стратегии внедрения сквозных технологий в VK мы решили определить единый для всех стек, за основу которого взяли Superset и Redash — все бизнес-юниты мигрировали свою аналитику на них.

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

Так от множества систем осталось всего три. Но и на этом не остановились: сейчас пробуем объединить их в одну, которая будет работать под капотом нашего решения VK Horizon.

Тренд № 2. Распространение использования BI

Нам важно, чтобы сбор и аналитика данных приносили пользу и помогали находить точки роста продуктов и внутренних метрик. Поэтому мы отслеживаем использование BI внутри VK.

Так, исследование, проведённое в июле 2025 года, показало, что 55% целевых сотрудников регулярно (зачастую — еженедельно) используют наши BI-решения, и эта метрика постепенно растёт.

Причем они не только просматривают уже существующие дашборды, но и активно создают новые под свои задачи. Сейчас соотношение creator-viewer за месяц — 1 к 8, но при сохранении трендов оно может уменьшиться до 1 к 6.

Тренд № 3. Повышение стабильности дашбордов и демократизация разработки отчётов

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

Но из-за ряда факторов это условие может не выполняться. Например:

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

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

  • В Superset есть Jinja — шаблонный движок для Python, который нужен для динамического формирования SQL-запросов и построения визуализаций. Он позволяет встраивать выражения, условия и значения переменных в шаблоны SQL, что делает работу с большими наборами данных более гибкой. Но нюанс в том, что особые значения фильтра могут сломать SQL с Jinja

  • В отдельных случаях из-за низкой производительности обработки графики на дашбордах могут загружаться и отображаться с большой задержкой

  • Данные на дашбордах могут быть необъективными, также их может быть недостаточно, чтобы принять решение

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

Именно поэтому мы в VK позволяем упрощать разработку отчётов. 

Раньше у нас в пайплайне было 5 этапов:

  • заказчик отдаёт ТЗ аналитику

  • аналитик обращается к дата-инженеру для построения витрин данных

  • дата-инженер формирует таблицу и отдаёт аналитику

  • аналитик составляет отчёт и отдаёт результаты заказчику

Это правильный путь. Но у него есть нюанс — time to market (TTM) отчёта в таком случае может составлять недели. Для нас это может быть критично, поскольку у нас динамическая среда — и при тестировании гипотез и подготовке новых релизов нам важно опираться на актуальные данные. 

Чтобы оптимизировать процесс, мы допускаем исключение из этой цепочки дата-инженера: так он может сфокусироваться на основных бизнес-задачах и процессах. Формировать виртуальные таблицы начал аналитик. Согласований и ожиданий стало меньше, то есть ускорился time to market.

Можно упростить процесс еще сильнее. Например, если заказчик умеет писать SQL, то мы исключим из цепочки не только дата-инженера, но и аналитика. Но такой self-service возможен только в условиях высокого уровня Data Governance, к которому мы ещё идём.

В итоге мы пришли к тому, что семантический слой DWH (Data Warehouse) часто хранится в виртуальных SQL-датасетах BI-системы, то есть наш TTM больше зависит не от количества участников и ответственных, а от качества существующих дашбордов и оптимизации системы хранения датасетов — именно эту задачу мы и решали.

Модель данных в Superset

Чтобы пояснить суть наших действий, разберём модель данных в Superset.

Она довольно простая:

  • дашборды строятся по графикам

  • графики строятся на основе двух типов датасетов: физических и виртуальных

  • датасеты формируются на основе данных из источников

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

Во многих BI-системах, в том числе Superset, есть встроенное кеширование. Благодаря этому получить данные, которые уже есть в кеше, будет значительно быстрее. Например, среднее время выполнения условного запроса к БД — 14 секунд, а среднее время загрузки из кеша — 0,8 секунды.

Есть нюанс: по нашим оценкам, обычно к БД направлены до 85% ежедневных запросов, и только в 15% случаев данные берутся из кеша. Во многом это происходит потому, что данные попадают в кеш, только если к ним кто-то уже обращался за последние сутки. Но у заказчиков могут быть разные контексты и потребности, и возможны ситуации, когда нужных данных может просто не оказаться в кеше. Поэтому мы решили прокачать работу кеша.

Первый этап: кеширование графиков по расписанию

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

При этом мы настроили отправку Alerts&Reports в VK Teams. Благодаря этому аналитики или другие пользователи узнают, что в кеше появились актуальные данные, дашборд обновлён.

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

  • get_tables: получаем источники дашборда

  • sensor: ожидаем сборку источников

  • warm_up: на основе статистики просмотров чартов прогреваем каждый график в топ-10 популярных значений фильтров

BI стал частью Data Platform, поскольку нам стало важно отслеживать триггеры и зависимости.

Уже на этом этапе мы получили буст по проценту попадания запросов в кеш и скорости загрузки. В кеш стали обращаться 26% запросов (вместо 15%), а скорость загрузки выросла на 12% (10,6 секунды против 12 секунд). 

Метрика

Было

Стало

Cache Miss

85%

74%

Avg Cache Load

0,8 с

-//-

Avg Query Load

14 с

-//-

Avg Load

12 c

10,6 с

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

Второй этап: ускоряем доступность данных из кеша

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

За это время система проверяет, можно ли конкретному пользователю отдавать запрашиваемый кеш. Она делает вывод на основе table-based access model (модели доступа на основе таблиц). Это можно было оптимизировать.

Основная сложность — нам нужна in-house проверка доступа пользователя к закешированным данным. Алгоритм проверки доступа должен быть максимально точным и работать быстро.

Изначально мы использовали sqlparse как библиотеку для извлечения таблиц из SQL. Но в рамках оптимизации решили заменить её самописным решением. Все основные отчёты у нас строятся на ClickHouse — и в первую очередь оптимизировать процессы нужно для неё. В результате разработали VK clickhouse-query-parser — библиотеку на Python. Она возвращает AST от SQL-запроса, на основе которого можно быстро извлечь используемые таблицы. VK clickhouse-query-parser использует бинарник, собранный из оригинального парсера ClickHouse. Поэтому наш парсер никогда не ошибается.

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

VK clickhouse-query-parser использует бинарный файл, собранный из C++ — это даёт стабильно высокую производительность.

С переходом на собственный парсер мы смогли выкрутить на максимум среднюю скорость загрузки данных из кеша: значение сократилось с 0,8 до 0,1 секунды. 

Метрика

Было

Стало

Cache Miss

85%

74%

Avg Cache Load

0,8 с

0.1 с

Avg Query Load

14 с

-//-

Avg Load

12 c

10,6 с

Осталось найти способ улучшить метрику Avg Query Load, то есть ускорить среднее время выполнения запросов. Важно было сделать это за счёт оптимизации системы хранения, а не переписывания запросов пользователей. 

Третий этап: повышение производительности выполнения запросов

Несмотря на то что есть кеш, нам всё равно часто нужно обращаться к базе данных. У нас много дашбордов — 769 основных, а всего более 6 000 — и комбинаций контекстов для каждого, поэтому всё уместить в кеше Redis просто невозможно. 

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

Мы проанализировали инструменты и выбрали VK ClickHouse API. Это наша библиотека-драйвер над ClickHouse, в которой есть упрощенная реализация MapReduce. В ней первый запрос выполняется на этапе map, а результат сохраняется во временную таблицу. Второй запрос, уже к полученной материализации, исполняется быстро благодаря предварительной обработке. Он сводит данные на этапе reduce.

К тому же у VK ClickHouse API есть много полезных фич:

  • контроль коннектов к кластеру — позволяет не перегрузить источник

  • сенсоры ожидания сборки таблиц-источников — защищают от использования неполных данных

  • высокая отказоустойчивость над ClickHouse — при сбое одной реплики он переключается на другую этого же шарда

Чтобы драйвер было удобно использовать, мы вынесли его в интерфейс Superset как опцию, которую в любой момент можно включить или выключить.

Покажем на примере, насколько эффективно работает VK ClickHouse API. 

Допустим, у нас есть запрос, который выполняется 5 минут. Или не выполняется вообще и завершается по таймауту.

Но после включения CH API он выполняется меньше чем за минуту.

Материализация собирается и складывается в ClickHouse. Затем начинается стадия reduce: при создании визуализации (Chart) источником будут предварительно подготовленные данные — запрос идёт к ним. Запросы для построения графика (Chart SQL) идут напрямую к готовым экстрактам. В интерфейсе мы помечаем, что сборка идёт на основе экстракта.

Запрос визуализации также становится проще и короче. Мы используем FROM $table, чтобы указать, что применяем материализацию.

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

Подготовка экстрактов датасетов помогает нам сократить среднее время выполнения запросов с 14 до 8 секунд. Также увеличилась и средняя скорость загрузки дашбордов на 43% — она составила 5,9 секунды вместо 12.

Метрика

Было

Стало

Cache Miss

85%

74%

Avg Cache Load

0,8 с

0,1 с

Avg Query Load

14 с

8 с

Avg Load

12 c

5,9 с

Схема работы экстрактов в VK Superset

Мы получили такой общий пайплайн:

  • Пользователь, открывая дашборд, часто попадает сразу в кеш: дефолтный контекст почти всегда есть в Redis Cache

  • При изменении внешнего фильтра используем высокодоступную материализацию в ClickHouse. Это позволяет отработать запрос за несколько секунд

  • Для динамических SQL-датасетов (с Jinja) нужно обращаться в ClickHouse-источник

  • Если нужны самые свежие данные — нужно настроить их репликацию в ClickHouse из распределённой системы хранения и обработки больших объёмов структурированных данных. 

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

Важно, что использование VK ClickHouse API в нашей реализации — опция. Пользователи по желанию могут выбирать между двумя вариантами пайплайна:

  • BI — cache — ClickHouse

  • BI — cache — VK CH API — ClickHouse

Краткое послесловие

Apache Superset — универсальный инструмент благодаря большому набору базовых функций и возможности гибкой кастомизации. Наш опыт показывает: чтобы повысить производительность решения, не обязательно изменять культуру разработки витрин данных и ограничивать построение дашбордов только аналитиками. Оптимизировать можно и работу самой системы. Благодаря интеграциям и разработанным технологиям мы добились двойного буста по скорости подготовки и отображения данных. Продолжаем оптимизировать реализацию SuperSet, переводя больше медленных сертифицированных дашбордов на схему с экстрактами.

Сталкивались ли вы с медленной загрузкой дашбордов при использовании open-source BI? Если да, как боролись с этим?

Комментарии (0)