Feature management в Тензоре

Привет, Хабр!

Меня зовут Данил Садриев, и я работаю руководителем одного из платформенных направлений в Тензоре. Наш продукт — Управление Облаком, аналог административных консолей AWS или Azure для сотрудников компании. Управление Облаком предоставляет большое число сервисов: от запуска контейнера до паркинга доменов. А также: хранит логи и статистику, управляет резервным копированием, в общем все, что нужно для полноценной разработки продукта. В этой статье я расскажу о сервисе управления функционалами. Возможно, это пригодится тем, кто готовится к секции интервью по system design, а также будет интересно начинающим product owner’ам, и архитекторам в части метода организации работы с данными.

При создании продукта часто возникают ситуации, когда необходимо на практике проверить гипотезу о том, что новый функционал или внешний вид будут эффективнее/привлекательнее для пользователей. Для задачи сравнения, пользователей необходимо разделить по тому или иному признаку. Иными словами, нужно провести сплит‑тест или А/В тестирование. Сам подход очень близок к клиническим испытаниям эффективности лекарственных препаратов. Истоки A/B‑тестирования при желании можно отнести к библейским временам, найти упоминания у Петрарки, но первым документированным описанием эксперимента на разных группах людей является «Трактат о цинге«Джеймса Линда 1753 года.

Заглавная страница оригинального трактата

Заглавная страница оригинального трактата

Цинга была основной причиной смертей, вызванных заболеванием, среди моряков в XVI-XVIII вв.  Джеймс Линд провел первое в мире клиническое исследование и доказал, что цитрусовые способны предотвратить развитие цинги.

Истории известен ещё один интересный эксперимент, вошедший в книгу британского ученого Роналда Фишера «Планирование экспериментов», изданную в 1935 г. Он описал один из тестов, получивший название «Леди, дегустирующая чай».

ce2a1ac780859053407998892506edfa.png

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

В наши дни, определенную известность получил эксперимент Google, иронично названный »50 оттенков синего».

Какой оттенок повысит вероятность перехода по ссылке?

Какой оттенок повысит вероятность перехода по ссылке?

В 2009 году Дуг Боуман, тогда главный дизайнер компании, назвал это одной из причин своего ухода. Компания показывала разные оттенки синего в рекламных рассылках определенному проценту пользователей. Слегка фиолетовый оттенок максимизировал вероятность того, что пользователи нажмут на рекламируемые ссылки, что в конечном счете дало компании Google ощутимый прирост доходов от рекламы.

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

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

eeb073976d8bc2d76b4873e340e2d584.png

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

Достоинства:

•      Очень удобный, всем понятный и простой способ изменения поведения сервиса;

•      Не требует сетевого вызова;

•      Параметры просты в реализации.

Недостатки:

•      Задание параметров в ini-файле — это простой, но плохо управляемый способ;

•      Большое количество параметров замедляет доступ к их значениям и расходует память сервиса;

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

•      Чтобы сервис узнал о новых параметрах, его надо перезагрузить или вызвать специальную процедуру применения параметров, когда сервис медленно один за другим завершает свои процессы и поднимает новые. Обе процедуры, если их делать массово для сотен сервисов, очень затратные по ресурсам ЦОД;

•      Параметры очень неудобно делать действующими для конкретного клиента или пользователя;

•      Параметры доступны только на сервисах. Во фронте параметры недоступны.

Иной подход к изменению поведения сервиса — переключатели функционала (feature toggles). Более подробно можно почитать, к примеру, здесь. Отметим лишь плюсы и минусы применительно к сервисам Тензора.

Достоинства:

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

•      Не требуется перезагрузка сервисов;

•      Можно использовать везде — фронт, бэк, мобильные приложения;

•      Использование переключателя можно наблюдать в статистике.

Недостатки:

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

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

•      Переключатели сложнее в реализации.

Соответствующий сервис для управления feature toggles в Тензоре называется «Управление функционалами»

dd7eb076147fbccff0ab3a01cba67c51.png

Его основные операции:

•      Ввод в работу нового функционала;  

•      Предоставление отчетов: сколько клиентов, каким функционалом пользуется и как давно;  

•      Ответ на вопрос — включен или выключен функционал для пользователя.

Состояние переключателей хранится в Postgres, начальный вариант архитектуры предусматривал nginx в качестве кэширующего кластера. Число rps было порядка 300, и с ростом вызовов и количества переключателей Postgres медленнее отдавал ответ:

899f8cec884fc6a8f9d4cf941c535495.png

Чтобы улучшить ситуацию, добавили Redis, и за счет кэширования нагрузка на сервис снизилась до 100 rps, среднее время ответа также уменьшилось (отметим, что число переключателей при этом возросло кратно):

f586da51ae7ed123ad4dcb1ca5a8788b.png

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

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

59fe861836a9f53a4fdd91562397c63f.jpg

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

Статистика числа вызовов за последние 12 месяцев

Статистика числа вызовов за последние 12 месяцев

Чтобы не перегружать статью, некоторые технические аспекты были опущены, но я с удовольствием отвечу на ваши вопросы в комментариях!

© Habrahabr.ru