Добрый день, сообщество!



Изначально я планировал написать статью в виде конспекта с доклада на devconf. Потом на меня снизошло понимание, что сорокапятиминутное выступление сложно переложить в статью на хабре, при этом оставив ее размер вменяемым. Поэтому в статье речь пойдет об архитектуре plus1.wapstart.ru, а слайды с конференции можно посмотреть здесь.

Plus1.wapstart.ru — это рекламная сеть для мобильного интернета. Наша «экосистема» — это рекламодатели, владельцы площадок (сайтов и приложений) и аудитория пользователей.
Владельцы площадок хотят максимально просто и эффективно монетизировать свою аудиторию, рекламодатели хотят эффективно вложить деньги, потребителей реклама должна как минимум не раздражать, а как максимум — они должны быть ей довольны.
Задача plus1.wapstart.ru — удовлетворение потребностей этих групп. Для нас их желания означают, что мы должны работать максимально быстро, не допускать ни минуты даутнайма и само собой следить за качеством и внешним видом рекламы.

Немного цифр:
  • Пиковая нагрузка > 103 динамических запросов в секунду.
  • В день мы показываем более ~ 107 объявлений.
  • Cуммарное число баннеров и площадок измеряется четырехзначными цифрами.
  • Среднее время отдачи баннера не превышает 90ms.


Если вам интересно как это всё работает — добро пожаловать под кат!


Железо




ПО


Мы стремимся к единообразию:
  • Фронты — freebsd, nginx.
  • Ферма (сервера приложений) — Debian GNU/Linux, php 5.3 fpm, onphp framework, memcached, свои демоны (о них мы расскажем в следующем докладе).
  • Сервера баз данных — Debian GNU/Linux, Postgres 9.0, репликация из коробки.
  • Обслуживающие сервера — Debian GNU/Linux, zabbix, pinba.

Как мы подбираем баннер




Главное правило — если что-то можно посчитать заранее, это нужно считать заранее.



Сам процесс выглядит примерно таким образом:
  • Мы разбираем запрос (http) на показ баннера. Из быстрого хранилища
    мы получаем характеристики этого запроса: определяем оператора по ip
    адресу, модель и операционную систему телефона по user-agent и другим
    заголовкам.
  • По каждой характеристике запроса мы получаем список баннеров,
    подходящий для этого запроса.
  • Пересекаем (intersect) списки.
  • Полученная совокупность баннеров проверяется дополнительными
    «чекерами». Это обусловлено тем, что некоторые проверки можно сделать
    только во время выполнения, т.к. они привязаны к конкретному запросу.
    Например, нет смысла показывать баннер пользователю, если он его уже
    видел 10 раз и не кликнул на него.

Как мы считаем статистику




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

Работает оно так:
  • Каждый сервер пишет статистические события (факт показа, факт клика, и т.д.) в файл в cериализованном виде.
  • Файл в имени содержит метку времени.
  • Обработчик файлов группирует записи из файла, «схлопывая» однородные события в одну запись, пишет полученный набор во временную таблицу в базу и архивирует файл.
  • Временная таблица содержит метку времени в имени. После ее аггрегации в часовые таблицы она удаляется (drop).
  • Из часовых таблиц строятся дневные таблицы, а из дневных — месячные. Данные в каждом виде таблиц имеют определенную давность хранения.

Мониторинг




Сейчас в качестве основного сервиса для мониторинга мы используем zabbix. Не могу сказать, что он быстр, но на нашем наборе триггеров и серверов работает вполне сносно. Мониторятся не только железные показатели (io, cpu, la) и показатели приложения (время отдачи, отрост логов), но и бизнес-метрики (коммерческая тайна :).
Для сбора оперативной статистики приложения мы используем pinba (о ней я уже писал :) ).
Наиболее критичные триггеры приходят к нам по sms.

Ошибки


Ошибки бывают у всех. Естественно, что разработчики должны знать об ошибках, причем желательно узнать о них до того как о них узнает пользователь. Для сбора ошибок мы используем syslog, благо php
умеет туда логгировать. Данные из syslog аггрегируются на обслуживающем сервере и раз в N минут отправляются по списку рассылки. Это позволяет оперативно отлавливать проблемы.

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

ps. Мы делимся с сообществом нашими наработками — https://github.com/Wapstart
pps. О том как мы «обманываем» наши приложения будет отдельный пост.