Лямбда-архитектура с обратной связью
TRANSCRIPT
ЛЯМБДА-АРХИТЕКТУРА С ОБРАТНОЙ СВЯЗЬЮНа примере системы управления ретаргетинговой рекламой в Facebook для онлайн туристических агентств
Александр Макеев, 2016 г.
ЗАДАЧА• В сфере туризма существует проблема длинного цикла продажи• Потенциальный клиент может летом зайти на сайт онлайн
туристического агентства (ОТА) чтобы подобрать тур на Новый год• Если сайт ОТА – это не Booking.com, то имеющиеся поисковые
алгоритмы едва ли умеют релевантно ранжировать списки отелей• После тщетных попыток что-то найти большинство клиентов уходят• Требуется инструмент для возврата потерянных клиентов• Один из таких инструментов – ретаргетинговая реклама• Этим и займёмся!
РЕТАРГЕТИНГОВАЯ РЕКЛАМАДва типа обычной ретаргетинговой рекламы:
1. Яркие фото девушек с кокосами на фоне изумрудного моря с крайне информативными лозунгами
«А ты готов к отдыху?»2. Ещё месяц вас будут преследовать
отели «ПО СКИДКАМ ТОЛЬКО СЕГОДНЯ», которые вы уже видели и закрыли потому что вам они не понравились
ЭтО раЗдрАжаеТ, ДА?
посмотрел
отели
ушёл
зашёл в Faceboo
kувидел
рекламу
зашёл на сайт
ОТАкруговорот
клиентав рекламе
ПРАВИЛЬНЫЙ РЕТАРГЕТИНГ
Через рекламу
предложить супер-
варианты
Понять клиент
а
Собрать
данные• Собрать все имеющиеся данные по каждому клиенту: параметры поиска, просмотренные отели, возвраты, отправленные заявки и т.д.
• На основании всей предыдущей истории создать портрет клиента: его предпочтения, финансовые возможности, семейное положение
• Подобрать статистически наиболее релевантные варианты отдыха и предложить их через ретаргетинговую рекламу
НЮАНСЫ СЕГМЕНТА ТУРИЗМА• Клиенты очень редко точно знают, что именно они хотят• В большинстве случаев более-менее стабильна только информация о
том, в какую страну хочет попасть турист, каким составом, примерные даты и начальный бюджет
• В отличии от розницы с номенклатурной базой максимум в тысячи позиций по каждой товарной группе, в туризме количество вариантов туров в одну страну исчисляется миллионами
• Нет возможности сделать кросс-продажу• Зато туристы каждый год куда-то путешествуют. И это круто!• С возрастом туриста растут бюджеты и предсказуемость
направлений
СИСТЕМА ДОЛЖНА ОБЕСПЕЧИВАТЬ• Сбор, хранение и первичный анализ исторических данных• Сегментацию пользователей на основании поисковых запросов• Получение актуальных цен на отели под каждый сегмент• Качественные рекомендации отелей основываясь на поведенческих
паттернах и собранной статистики• Создание изображений отелей с дополнительными
информационными слоями (названия отелей, параметры сегментов, цены, скидки)
• Создание и обновление рекламных объявлений• Сбор и обработку рекламной аналитики Facebook
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-
Load
Рекомендательная система
Актуализатор цен на
отели
Генератор изображени
й
Система публикации объявлений
Сбор и обработка
статистики FB
Lamda architecture
Facebook Ads system
Логи
рова
ние
и мо
нито
ринг
Clos
ed-lo
op
СБОР ДАННЫХ О ПОЛЬЗОВАТЕЛЯХ
• Цель: сбор всех доступных данных о посещении каждой страницы в рамках сессии каждого посетителя
• Трекер активности посетителей сайта• Фротент-часть на JS
• Переработанный скрипт Piwik• Бекенд-часть на Go
• NGINX reverse-proxy• 4-8 golang backends
• Является прокси-слоем к алгоритмам рекомендательной системы
• Возвращает JSONP список рекомендованных отелей
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-
Load
Рекомендательная система
Актуализатор цен на
отели
Генератор изображени
й
Система публикации объявлений
Сбор и обработка
статистики FB
ЛЯМБДА-АРХИТЕКТУРА• Быстрое in-memory хранилище для данных пользователей с
активными сессиями• Медленное постоянное хранилище для всех исторических данных
(сохранение с потенциальной задержкой)• Данные всегда хранятся в первозданном виде для дальнейших
манипуляций• Как правило кортежи очень широкие: десятки атрибутов• В классической архитектуре преобразование и формирование
датасета (выполнение функции трансформации) производится на лету в serving-слое используя данные из обоих хранилищ
• Отличие от классики: перед преобразованием данные из постоянного хранилища один раз загружаются в сессионное. Далее данные записываются одновременно в оба хранилища, но serving-слой использует только сессионное.
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-
Load
Рекомендательная система
Актуализатор цен на
отели
Генератор изображени
й
Система публикации объявлений
Сбор и обработка
статистики FB
ХРАНЕНИЕ ИСТОРИЧЕСКИХ ДАННЫХ
• Данные хранятся в виде иммутабельных raw-логов• Постоянное хранилище
• Сейчас используется MongoDB• После выхода за пределы возможностей – Hadoop/HBase
• Сессионное хранилище• Используется Redis (в дальнейшем – Aerospike)• При активизации сессии пользователя из постоянного
хранилища загружаются все его исторические данные• Все последующие события в рамках сессии сохраняются
одновременно в сессионное и постоянное хранилища• Время жизни данных – несколько часов
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-
Load
Рекомендательная система
Актуализатор цен на
отели
Генератор изображени
й
Система публикации объявлений
Сбор и обработка
статистики FB
EXTRACT TRANSFORM LOAD• Слой обработки сырых данных• На выходе – датасет, пригодный для дальнейшей работы
рекомендательной системы• Сейчас с объёмом данных справляется однопоточный
обработчик, в дальнейшем Hadoop + Spark + Python• В realtime используется для получения обработанной
истории конкретного пользователя• В пакетном режиме используется для получения
обработанной истории всех пользователей, на которой проводится обучение алгоритмов рекомендательной системы
• Языки реализации слоя: Go и Python
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-
Load
Рекомендательная система
Актуализатор цен на
отели
Генератор изображени
й
Система публикации объявлений
Сбор и обработка
статистики FB
КРИТЕРИИ ВЫБОРА ХРАНИЛИЩ• MongoDB
• schemaless• fast• scalable
• Redis• fast
• Hbase• columnar• scalable
• Aerospike• extremely fast• scalable• powerful inline scripting language Lua
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-
Load
Рекомендательная система
Актуализатор цен на
отели
Генератор изображени
й
Система публикации объявлений
Сбор и обработка
статистики FB
РЕКОМЕНДАТЕЛЬНАЯ СИСТЕМА• Входные данные:
• История просмотров страниц• Активные пользовательские сегменты• История отправки заявок на туры• История продаж из CRM• Статистика рекламных объявлений из Facebook Insights
• Алгоритмы:• Для пользователей без истории – статистически наиболее
эффективные предложения для каждого сегмента• При наличии истории просмотров – мульти-классовая
классификация с помощью XGBoost (получение вероятности по каждому классу-отелю)
• В разработке – классификация с помощью нейронной сети прямого распространения
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-
Load
Рекомендательная система
Актуализатор цен на
отели
Генератор изображени
й
Система публикации объявлений
Сбор и обработка
статистики FB
Redis
АРХИТЕКТУРА РЕКОМЕНДАТЕЛЬНОЙ
СИСТЕМЫСбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-
Load
Рекомендательная система
Актуализатор цен на
отели
Генератор изображени
й
Система публикации объявлений
Сбор и обработка
статистики FBСервис обучения XGBoost
ХранилищеETL
Сохранённая в файл модель
XGBoostXGBoostXGBoost
Пул микросервисоврекомендательной системы
raw data
dataset withgenerated features
опов
ещен
ия с
ерви
сов
об и
змен
ении
мод
ели
Realtime tracker json
Supervisor
NGINXjson
states
cacheRedis
ОБУЧЕНИЕ МОДЕЛИ РЕКОМЕНДАТЕЛЬНОЙ СИСТЕМЫ
• Через заданный промежуток времени cron-задача закидывает в RabbitMQ сообщение о том, что нужно переобучить модель
• Процесс, занимающийся обучением, получает сообщение и производит действия:• Вычитка всех накопленных исторических данных• Первичная очистка от кортежей, которые не могут быть
использованы при обучении модели• Формирование финального Python Pandas DataFrame
• One-hot encoding• Normalizing
• Тренировка xgboost.XGBClassifier• Проверка качества модели
• Сохранение модели в файл• Запись в Redis структуры с данными о новой модели
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-
Load
Рекомендательная система
Актуализатор цен на
отели
Генератор изображени
й
Система публикации объявлений
Сбор и обработка
статистики FB
ОБЗОР МИКРОСЕРВИСОВ• Основная нагрузка рекомендательной системы
приходится на пул микросервисов• Каждый микросервис – это однопоточное
приложение на Python + Tornado на отдельном порту• Микросервисы запускаются и мониторятся с
помощью Supervisor• Для всего пула в качестве фронтенд и
балансировщика нагрузки используется NGINX
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-
Load
Рекомендательная система
Актуализатор цен на
отели
Генератор изображени
й
Система публикации объявлений
Сбор и обработка
статистики FB
ЗАГРУЗКА НОВОЙ МОДЕЛИ• В Redis хранится ID самой свежей модели• Во время инициализации микро-сервис получает ID
текущей модели, загружает её из файла и инициализирует экземпляр XGBoost
• С имеющейся рассчитанной и предзагруженной моделью сервис отвечает на запросы
• После каждого запроса происходит проверка на наличие новой модели
• Если появилась новая модель, то сервис просто завершает свою работу и вместо него Supervisor запускает новый экземпляр сервиса
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-
Load
Рекомендательная система
Актуализатор цен на
отели
Генератор изображени
й
Система публикации объявлений
Сбор и обработка
статистики FB
ОБРАБОТКА ЗАПРОСА• Запрос к сервису содержит ID пользователя, для
которого необходимо сделать рекомендацию отелей• Сервис проверяет наличие необходимых данных в
сессионном хранилище• Если данные не полные, то догружает недостающие из
постоянного хранилища в сессионное• Формирует датасет, пригодный для работы XGBoost:
• Cleaning• One-hot encoding• Normalizing
• Выполняет предзагруженную модель• Возвращает список ID рекомендованных отелей
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-
Load
Рекомендательная система
Актуализатор цен на
отели
Генератор изображени
й
Система публикации объявлений
Сбор и обработка
статистики FB
ПРОБЛЕМЫ ПРОГНОЗИРОВАНИЯ• Недостаточный объём данных для обучения алгоритмов
рекомендательной системы• Огромное количество отелей и как следствие необходимость
собирать огромное количество данных для обучения• Невозможность использовать основную метрику качества
рекомендаций – конверсию в клиенты• Многоканальная природа продаж пакетных туров• Невозможность учёта факторов качества оффлайн-
обслуживания клиентов• Большое количество субъективных факторов при
окончательном выборе места отдыха• Проблема long-tail из статистически непопулярных отелей,
выбор которых не попадает под статистически значимые поведенческие паттерны
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-
Load
Рекомендательная система
Актуализатор цен на
отели
Генератор изображени
й
Система публикации объявлений
Сбор и обработка
статистики FB
АКТУАЛИЗАТОР ЦЕНОВЫХ ПРЕДЛОЖЕНИЙ
• Непрерывно работающий сервис, получающий обновлённые ценовые предложения от операторов
• Цены получаем в разрезе каждого из сегментов• Сохраняется история изменения цен• На основании истории производится поиск резких
падений цен• Для найденных предложений в рекламных
объявлениях указывается процент падения цены• Актуальные цены используются при формировании
продуктового каталога для рекламной системы FB
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-
Load
Рекомендательная система
Актуализатор цен на
отели
Генератор изображени
й
Система публикации объявлений
Сбор и обработка
статистики FB
ГЕНЕРАТОР ИЗОБРАЖЕНИЙ• Каждое изображение формируется индивидуально под
каждый рекламный блок• На изображение отеля накладываются слои:
• название• некоторые параметры сегмента• актуальная цена• процент снижения цены
• URL изображения используется при формировании продуктового каталога
• Для формирования изображений используется PHP+GD• Количество соответствует объёму генерируемого
продуктового каталога: сотни тысяч изображений
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-
Load
Рекомендательная система
Актуализатор цен на
отели
Генератор изображени
й
Система публикации объявлений
Сбор и обработка
статистики FB
ПУБЛИКАЦИЯ ОБЪЯВЛЕНИЙ• Используется Facebook Ads API• Чтобы соответствовать требованиям и ограничениям
API для каждого аккаунта создаётся собственная очередь в RabbitMQ и монопольный консьюмер, отправляющий запросы к API
• Для каждой страны создаётся рекламная кампания, внутри которой единоразово формируются рекламные объявления, использующие каталоги продуктов
• Свежие каталоги продуктов формируются и загружаются в FB после каждой завершённой актуализации цен
• Для работы с Facebook API используется PHP
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-
Load
Рекомендательная система
Актуализатор цен на
отели
Генератор изображени
й
Система публикации объявлений
Сбор и обработка
статистики FB
ГРУППИРОВКА ЗАДАЧ RABBITMQ• Публикация объявлений – комплексная задача, состоящая из
нескольких шагов:• Получение актуальных цен• Создание рекламной кампании• Генерация изображений• Формирование продуктового каталога• Публикация каталога
• Некоторые подзадачи можно делать параллельно, некоторые строго одну за другой. Одна задача может после своего выполнения добавить в очередь следующую.
• Каждому пакету задач задаётся уникальный ID, по которому можно отследить прогресс выполнения задачи или определить по логам место сбоя
• В планах: механизм конфигурирования взаимосвязей между подзадачами и автоматизация запуска последовательностей
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-Load
Рекомендательная система
Актуализатор цен на отели
Генератор изображений
Система публикации объявлений
Сбор и обработка статистики FB
СБОР И ОБРАБОТКА СТАТИСТИКИ• Для получения статистики используется FB Ads Insights
API• Сбор статистики производится cron-задачей раз в сутки• Статистика собирается и суммируется в разрезе
каждого отеля• Основной критерий оценки – CTR• Отели с низким CTR:
• имеют пониженный весовой коэффициент в алгоритмах рекомендательной системы
• уходят на модерацию в админку• могут быть полностью удалены из ротации
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-Load
Рекомендательная система
Актуализатор цен на отели
Генератор изображений
Система публикации объявлений
Сбор и обработка статистики FB
ОБРАТНАЯ СВЯЗЬ• Результат работы рекомендательной системы
используется для показа рекламных объявлений• Главный критерий качества работы
рекомендательной системы – конверсия, но использовать её для оптимизации алгоритма невозможно из-за длинного цикла продажи
• В качестве критерия качества используется CTR• Обратная связь внутри рекламной системы:
1. результат работы алгоритма рекомендаций ротируется в рекламе
2. собираются метрики качества объявлений3. метрики являются одним из основных факторов
в работе алгоритма рекомендательной системы
Анализ поведения аудитории
Формирование рекомендаций
Показ рекламных объявлений
Анализ статистики
СЛОЖНОСТИ РЕАЛИЗАЦИИ• Разрывы в общем потоке данных (FB privacy agreement):
• нет технической возможности узнать через FB API какие именно объявления, в какой последовательности и сколько раз были показаны каждому из посетителей
• нет возможности узнать, кому именно мы рекомендуем предложения по отелям
• Таким образом система работает с полностью анонимизированными посетителями
• Все этапы работы системы сильно растянуты во времени и фактически между этапами получения данных из трекера, работы рекомендательной системы, реакцией пользователей на объявления, сбором статистики и приходом агрегированных метрик в виде фич в модель рекомендательной системы, могут проходить часы или даже дни
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-Load
Рекомендательная система
Актуализатор цен на отели
Генератор изображений
Система публикации объявлений
Сбор и обработка статистики FB
ИСТОЧНИКИ ДАННЫХ• Activity tracker (Go)
• Requests log• Responses• Errors
• Redis comsumers (PHP)• Execution progress• Errors
• Recommendation service (Python)• Requests log• Errors
• Admin backend (PHP)• Errors
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-Load
Рекомендательная система
Актуализатор цен на отели
Генератор изображений
Система публикации объявлений
Сбор и обработка статистики FB
ELASTICSEARCH + LOGSTASH• Логирование с помощью UDP-сообщений в Logstash
• очень быстро• но что-то может бесследно исчезнуть
• Далее Logstash пакетами сохраняет лог в Elasticsearch• возможность полнотекстового поиска• визуализация данных с помощью Kibana
• Кроме текста сообщения сохраняются:• дата и время• источник• PID процесса• код сообщения• уровень сообщения (error, warning, etc)• ID сообщения в случае пакетной обработки• Error trace
Сбор данных о пользователях
Сессионное хранилище
Постоянное хранилище
Extract-Transform-Load
Рекомендательная система
Актуализатор цен на отели
Генератор изображений
Система публикации объявлений
Сбор и обработка статистики FB
НАГРУЗОЧНОЕ ТЕСТИРОВАНИЕ• Тестовая конфигурация сервера: 8
ядерный Intel(R) Xeon(R) CPU E3-1271 v3 @ 3.60GHz, RAID1 SSD, 32Gb RAM
• NGINX with upstream 10 Go tracker processes
• Нагрузка: соседний сервер в том же ДЦ, скрипт:
• Запросы идут на трекинг просмотра страницы и получение списка рекомендованных отелей без использования кеширования
• Результаты тестирования стабильны при любом количестве конкурентных клиентов: 1300-1400 запросов в секунду
• Bottleneck: количество ядер процессора (почти 100% загрузка)
• Решение потенциальной проблемы: горизонтальное масштабирование
• На данный момент односерверное решение гарантирует обработку трафика в 30 миллионов запросов в сутки при расчёте что 50% трафика приходится на 3 самых активных часа суток
• Это полностью покрывает потребности всего украинского туристического рынка
#!/bin/shfor i in 1 10 20 50 100 200do ab -n 10000 -c $i -e log-${i}.csv -g plot-${i}.tsv URLdone