Добрый день, сообщество!
Изначально я планировал написать статью в виде конспекта с доклада на devconf. Потом на меня снизошло понимание, что сорокапятиминутное выступление сложно переложить в статью на хабре, при этом оставив ее размер вменяемым. Поэтому в статье речь пойдет об архитектуре plus1.wapstart.ru, а слайды с конференции можно посмотреть здесь.
Plus1.wapstart.ru — это рекламная сеть для мобильного интернета. Наша «экосистема» — это рекламодатели, владельцы площадок (сайтов и приложений) и аудитория пользователей.
Владельцы площадок хотят максимально просто и эффективно монетизировать свою аудиторию, рекламодатели хотят эффективно вложить деньги, потребителей реклама должна как минимум не раздражать, а как максимум — они должны быть ей довольны.
Задача plus1.wapstart.ru — удовлетворение потребностей этих групп. Для нас их желания означают, что мы должны работать максимально быстро, не допускать ни минуты даутнайма и само собой следить за качеством и внешним видом рекламы.
Немного цифр:
- Пиковая нагрузка > 103 динамических запросов в секунду.
- В день мы показываем более ~ 107 объявлений.
- Cуммарное число баннеров и площадок измеряется четырехзначными цифрами.
- Среднее время отдачи баннера не превышает 90ms.
Если вам интересно как это всё работает — добро пожаловать под кат!
Железо
![](https://habrastorage.org/storage2/fb5/005/c45/fb5005c45bcd3a36a9b7cade9fac02ec.png)
ПО
Мы стремимся к единообразию:
- Фронты — freebsd, nginx.
- Ферма (сервера приложений) — Debian GNU/Linux, php 5.3 fpm, onphp framework, memcached, свои демоны (о них мы расскажем в следующем докладе).
- Сервера баз данных — Debian GNU/Linux, Postgres 9.0, репликация из коробки.
- Обслуживающие сервера — Debian GNU/Linux, zabbix, pinba.
Как мы подбираем баннер
![](https://habrastorage.org/storage2/ae0/9ed/49f/ae09ed49f79a359526177c5b1e5eea6e.png)
Главное правило — если что-то можно посчитать заранее, это нужно считать заранее.
![](https://habrastorage.org/storage2/d9e/692/927/d9e692927a4a10b34832fd0aa3f376fc.png)
Сам процесс выглядит примерно таким образом:
- Мы разбираем запрос (http) на показ баннера. Из быстрого хранилища
мы получаем характеристики этого запроса: определяем оператора по ip
адресу, модель и операционную систему телефона по user-agent и другим
заголовкам. - По каждой характеристике запроса мы получаем список баннеров,
подходящий для этого запроса. - Пересекаем (intersect) списки.
- Полученная совокупность баннеров проверяется дополнительными
«чекерами». Это обусловлено тем, что некоторые проверки можно сделать
только во время выполнения, т.к. они привязаны к конкретному запросу.
Например, нет смысла показывать баннер пользователю, если он его уже
видел 10 раз и не кликнул на него.
Как мы считаем статистику
![](https://habrastorage.org/storage2/96e/bc1/173/96ebc1173d0bf6af588fd8b1c338c419.png)
Надо быть всегда готовыми к росту. Процессы надо закладывать таким образом, чтобы их можно было легко распараллелить.
Работает оно так:
- Каждый сервер пишет статистические события (факт показа, факт клика, и т.д.) в файл в cериализованном виде.
- Файл в имени содержит метку времени.
- Обработчик файлов группирует записи из файла, «схлопывая» однородные события в одну запись, пишет полученный набор во временную таблицу в базу и архивирует файл.
- Временная таблица содержит метку времени в имени. После ее аггрегации в часовые таблицы она удаляется (drop).
- Из часовых таблиц строятся дневные таблицы, а из дневных — месячные. Данные в каждом виде таблиц имеют определенную давность хранения.
Мониторинг
![](https://habrastorage.org/storage2/c4c/faf/a25/c4cfafa251c80d893321292f72d6fc43.png)
Сейчас в качестве основного сервиса для мониторинга мы используем zabbix. Не могу сказать, что он быстр, но на нашем наборе триггеров и серверов работает вполне сносно. Мониторятся не только железные показатели (io, cpu, la) и показатели приложения (время отдачи, отрост логов), но и бизнес-метрики (коммерческая тайна :).
Для сбора оперативной статистики приложения мы используем pinba (о ней я уже писал :) ).
Наиболее критичные триггеры приходят к нам по sms.
Ошибки
Ошибки бывают у всех. Естественно, что разработчики должны знать об ошибках, причем желательно узнать о них до того как о них узнает пользователь. Для сбора ошибок мы используем syslog, благо php
умеет туда логгировать. Данные из syslog аггрегируются на обслуживающем сервере и раз в N минут отправляются по списку рассылки. Это позволяет оперативно отлавливать проблемы.
На этом, пожалуй, можно закончить. Диалог можно будет продолжить в комментариях. Наша команда с радостью ответит на ваши вопросы.
ps. Мы делимся с сообществом нашими наработками — https://github.com/Wapstart
pps. О том как мы «обманываем» наши приложения будет отдельный пост.