Привет, Хабр!
Меня зовут Данил Садриев, и я работаю руководителем одного из платформенных направлений в Тензоре. Наш продукт — Управление Облаком, аналог административных консолей AWS или Azure для сотрудников компании. Управление Облаком предоставляет большое число сервисов: от запуска контейнера до паркинга доменов. А также: хранит логи и статистику, управляет резервным копированием, в общем все, что нужно для полноценной разработки продукта. В этой статье я расскажу о сервисе управления функционалами. Возможно, это пригодится тем, кто готовится к секции интервью по system design, а также будет интересно начинающим product owner’ам, и архитекторам в части метода организации работы с данными.
При создании продукта часто возникают ситуации, когда необходимо на практике проверить гипотезу о том, что новый функционал или внешний вид будут эффективнее/привлекательнее для пользователей. Для задачи сравнения, пользователей необходимо разделить по тому или иному признаку. Иными словами, нужно провести сплит‑тест или А/В тестирование. Сам подход очень близок к клиническим испытаниям эффективности лекарственных препаратов. Истоки A/B‑тестирования при желании можно отнести к библейским временам, найти упоминания у Петрарки, но первым документированным описанием эксперимента на разных группах людей является «Трактат о цинге» Джеймса Линда 1753 года.
Цинга была основной причиной смертей, вызванных заболеванием, среди моряков в XVI-XVIII вв. Джеймс Линд провел первое в мире клиническое исследование и доказал, что цитрусовые способны предотвратить развитие цинги.
Истории известен ещё один интересный эксперимент, вошедший в книгу британского ученого Роналда Фишера «Планирование экспериментов», изданную в 1935 г. Он описал один из тестов, получивший название «Леди, дегустирующая чай».
Английский чай можно приготовить двумя способами: сначала налить в чашку молоко, а потом чай или наоборот. Фишер организовал эксперимент, в ходе которого леди должна была определить способ приготовления восьми чашек чая, представленных в случайном порядке. В ходе дегустации леди смогла правильно классифицировать все чашки.
В наши дни, определенную известность получил эксперимент Google, иронично названный «50 оттенков синего».
В 2009 году Дуг Боуман, тогда главный дизайнер компании, назвал это одной из причин своего ухода. Компания показывала разные оттенки синего в рекламных рассылках определенному проценту пользователей. Слегка фиолетовый оттенок максимизировал вероятность того, что пользователи нажмут на рекламируемые ссылки, что в конечном счете дало компании Google ощутимый прирост доходов от рекламы.
Данный эпизод показывает постепенное изменение метода принятия решений о внешнем облике продукта от субъективного мнения в сторону численных методов, и на этом вводную часть можно считать законченной.
В целом, задать поведение сервиса или приложения можно несколькими способами. Один из них — это параметры (могут храниться в переменных окружения, ini‑файле, или получаться из базы данных).
Почти любой сервис в облаках Тензора при старте получает наборы данных в виде строк (ключ, значение). Доступ к значению параметра обычно получают вызовом из кода, и дальше, в зависимости от результата, код идет по одной или другой ветке, изменяя поведение сервиса.
Достоинства:
-
Очень удобный, всем понятный и простой способ изменения поведения сервиса;
-
Не требует сетевого вызова;
-
Параметры просты в реализации.
Недостатки:
-
Задание параметров в ini-файле — это простой, но плохо управляемый способ;
-
Большое количество параметров замедляет доступ к их значениям и расходует память сервиса;
-
Трудно отследить, когда параметры перестали использоваться в коде и их следует удалить. Со временем они превращаются в мусор;
-
Чтобы сервис узнал о новых параметрах, его надо перезагрузить или вызвать специальную процедуру применения параметров, когда сервис медленно один за другим завершает свои процессы и поднимает новые. Обе процедуры, если их делать массово для сотен сервисов, очень затратные по ресурсам ЦОД;
-
Параметры очень неудобно делать действующими для конкретного клиента или пользователя;
-
Параметры доступны только на сервисах. Во фронте параметры недоступны.
Иной подход к изменению поведения сервиса — переключатели функционала (feature toggles). Более подробно можно почитать, к примеру, здесь. Отметим лишь плюсы и минусы применительно к сервисам Тензора.
Достоинства:
-
Состояние переключателя можно задавать как для крупных множеств клиентов, так и для конкретного пользователя;
-
Не требуется перезагрузка сервисов;
-
Можно использовать везде — фронт, бэк, мобильные приложения;
-
Использование переключателя можно наблюдать в статистике.
Недостатки:
-
В целом, обращение к состоянию переключателя в некоторых случаях может оказаться существенно дороже обращения к параметру. Переключатели хорошо кэшируются, но могут затребовать сетевое взаимодействие, а оно ненадежно.
-
В силу распределенности наших сервисов изменения состояния переключателей не происходит одновременно в разных частях облака Тензора, а с некоторым лагом.
-
Переключатели сложнее в реализации.
Соответствующий сервис для управления feature toggles в Тензоре называется «Управление функционалами»
Его основные операции:
-
Ввод в работу нового функционала;
-
Предоставление отчетов: сколько клиентов, каким функционалом пользуется и как давно;
-
Ответ на вопрос — включен или выключен функционал для пользователя.
Состояние переключателей хранится в Postgres, начальный вариант архитектуры предусматривал nginx в качестве кэширующего кластера. Число rps было порядка 300, и с ростом вызовов и количества переключателей Postgres медленнее отдавал ответ:
Чтобы улучшить ситуацию, добавили Redis, и за счет кэширования нагрузка на сервис снизилась до 100 rps, среднее время ответа также уменьшилось (отметим, что число переключателей при этом возросло кратно):
Однако, в ходе эксплуатации столкнулись с тем, что nginx при кэшировании создавал очень много файлов, приходилось периодически его сбрасывать (удалять файлы), поэтому от него решили отказаться, но для этого сервис управления функционалами нужно было подготовить к высокой нагрузке.
Пропускную способность сервиса расширили за счет использования в коде корутин, дополнительной таблицы в Postgres и ключа setnx в Redis. Если Redis кластер оказывается пустым, вероятны очереди, поскольку каждый запрос также пойдет на сервис управления функционалами с требованием восстановить в кэше значение запрашиваемого переключателя. Для решения этой проблемы в Postgres создана таблица f_redis, в которой на сервисе мы храним абсолютно тоже самое, что и в Redis. Эта буферная таблица служит предохранителем после обновления Redis. На схеме ниже изображен упрощенный процесс прохождения запроса.
Сейчас среднее количество вызовов к сервису за сутки приближается к 108, при этом время отклика осталось на прежнем уровне, а это значит, что сервис успешно справляется с нагрузками:
Чтобы не перегружать статью, некоторые технические аспекты были опущены, но я с удовольствием отвечу на ваши вопросы в комментариях!
ссылка на оригинал статьи https://habr.com/ru/articles/829446/
Добавить комментарий