System Design Space
Граф знанийНастройки

Обновлено: 9 апреля 2026 г. в 15:55

Платформа A/B-тестирования

средний

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

Платформа A/B-тестирования ценна не дашбордом, а тем, насколько точно она умеет назначить вариант, зафиксировать показ и не подменить причинный сигнал шумом данных.

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

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

Назначение варианта

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

События экспозиции

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

Чистота метрик

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

Безопасность запуска

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

Постановка задачи

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

Функциональные требования

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

Управление экспериментами

  • Создание экспериментов с контрольным и тестовым вариантами
  • Настройка аудитории, ограничений и правил запуска
  • Определение длительности и условий остановки
  • Выбор основных и защитных метрик

Назначение вариантов

  • Детерминированное распределение пользователей по бакетам
  • Стабильное назначение одного и того же варианта
  • Поддержка долей трафика 1%, 5%, 50% и дальше
  • Постепенное расширение и быстрый откат эксперимента

Сбор данных

  • Логирование показа варианта и продуктовых событий
  • Привязка каждого события к эксперименту и бакету
  • Агрегация доли кликов, конверсии, удержания и защитных метрик

Анализ результатов

  • Расчёт статистической значимости и доверительных интервалов
  • Сравнение сегментов, защитных ограничений и основных метрик
  • Оперативные дашборды и итоговые отчёты

Нефункциональные требования

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

Критично

Быстрый ответ

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

Важно

Стабильное назначение

Пользователь должен видеть один и тот же вариант на всём протяжении эксперимента

Масштаб

Поток событий

Контур аналитики должен принимать и обрабатывать миллиарды событий в день без деградации

Высокоуровневая архитектура

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

Основные компоненты

Сервис управления экспериментами

Хранит конфигурацию, аудиторию, защитные ограничения и доли трафика

Сервис назначения варианта

Вычисляет бакет пользователя и возвращает решение на критичном пути

Контур приёма событий

Принимает показы, клики и конверсии с привязкой к экспериментам и вариантам

Контур анализа

Считает метрики, доверительные интервалы и итоговую статистику

🧪

Архитектура разделяет быстрое принятие решения и отдельный аналитический контур.
Ошибка в первом ломает UX, ошибка во втором ломает доверие к результату.

Визуализация через C4

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

L1 — Контекст системы

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

ПользовательWeb / MobileПродуктовоеприложениеПлатформаA/B-тестированияназначение, события, аналитикаПанельаналитикиПлатформаданныхзапрос вариантарезультатысобытия

Алгоритмы рандомизации

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

Хэширование и разбиение (HP)

Рекомендуемый
variant = Hash(UserID + ExperimentID) % 100
if variant < 50: return "Control"
else: return "Treatment"
  • Не требует отдельного состояния для назначения
  • Детерминирован: один и тот же вход даёт один и тот же выход
  • Обеспечивает независимость экспериментов за счёт ExperimentID
  • Легко масштабируется

Псевдослучайное назначение с кэшированием (PwC)

Альтернатива

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

  • На сервере требует базу или распределённый кэш
  • На клиенте обычно опирается на cookie или локальное хранилище
  • Требует дополнительного хранилища
  • Может ломать стабильность варианта при очистке cookie или потере записи

Методы назначения вариантов

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

Серверное назначение

  • Безопаснее: логика эксперимента не уходит на клиент
  • Подходит для тестов на backend-логике и API
  • Требует очень быстрого сервиса или локальной библиотеки
  • Добавляет сетевой переход в критичный путь

Клиентское назначение

  • Хорошо подходит для UI-изменений и быстрых экранных тестов
  • Не требует отдельного вызова на каждый рендер
  • Конфигурацию нужно заранее доставить на устройство
  • Пользователь видит логику и часть конфигурации

Оптимизация: доставка конфигурации ближе к продукту

Конфигурацию экспериментов выгодно заранее доставлять в Redis, на пограничные узлы или через сеть доставки контента (CDN). Тогда SDK или локальная библиотека могут вычислять вариант рядом с продуктом, а правила расширения трафика остаются централизованными.

Конвейер данных

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

📱

События клиента

📨

Kafka

Flink/Spark

🗄️

ClickHouse

📊

Отчёты

Приём

События летят в Kafka или похожий журнал. В записи обычно лежат user_id, experiment_id, variant, timestamp и полезная нагрузка события.

Обработка

Flink считают оперативные метрики и защитные проверки, а Spark или batch-задачи помогают собирать более тяжёлую аналитику и пересчёты.

Хранение и отчётность

OLAP-хранилище вроде ClickHouse или Pinot обслуживает быстрые аналитические запросы, а поверх него строятся оперативные панели и итоговые отчёты.

Параллельные эксперименты

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

Проблема

Эксперимент A тестирует поиск, эксперимент B меняет кнопку. Если пользователь попадает сразу в оба теста, становится трудно объяснить, какой именно фактор сдвинул конверсию.

Решение: домены и слои

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

Пример разбиения по слоям

Слой UI → [тест цвета кнопки, тест раскладки] (взаимоисключающие)
Слой поиска → [тест алгоритма ранжирования] (независимый)
Слой рекомендаций → [тест ML-модели] (независимый)

Типичные ошибки

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

Sample Ratio Mismatch (SRM)

Система ждёт распределение 50/50, а в реальности получает 52/48. Причины бывают разными: бот-трафик, потери при редиректах, ошибки клиентского кода и неучтённые фильтры на входе. Такие расхождения всегда нужно проверять до анализа метрик.

Преждевременный просмотр результатов

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

Сетевые эффекты

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

Множественное тестирование

Чем больше метрик одновременно смотрит команда, тем выше риск случайно найти «победу». Поэтому заранее выделяют основную метрику и, если нужно, применяют поправки вроде Bonferroni.

Ключевые выводы

Хэширование по user_id и experiment_id даёт детерминированное назначение без отдельного состояния и хорошо масштабируется горизонтально.

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

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

Отдельный событийный конвейер на Kafka и Flink/Spark нужен, чтобы аналитика не мешала пользовательскому пути.

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

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

Материал опирается на публичное интервью «System Design Interview: A/B Testing Platform» и статью Ron Kohavi «Trustworthy Online Controlled Experiments»

Связанные главы

Чтобы отмечать прохождение, включи трекинг в Настройки