Архитектура Pinterest
Pinterest — по непонятным для меня причинам
популярная в определенных кругах социальная сеть, построенная вокруг
произвольных картинок чаще всего не собственного производства. Как и
Instagram
проект довольно молодой, с очень похожей историей и стеком технологий.
Тем не менее, Pinterest определенно заслуживает внимания как один из
самых быстрорастущих по посещаемости вебсайтов за всю историю.
Платформа
- Amazon AWS — хостинг и вспомогательные
сервисы - nginx — вторичная балансировка нагрузки, отдача
статики - Python — язык программирования
- Django — фреймворк
- MySQL — основная СУБД
- memcached — кэширование объектов
- Redis — кэширование коллекций объектов
- Solr — поиск
- Hadoop — анализ данных
Статистика
- 3 миллиона уникальных посетителей в день
- 18 миллионов уникальных посетителей в месяц
- 4-я по популярности социальная сеть в США после
Facebook, Twitter и
LinkedIn - Порядка 500 виртуальных машин в EC2
- 80 миллионов объектов в S3
- 410Тб пользовательских данных
Развитие
Март 2010
- 1 маленький виртуальный веб-сервер
- 1 маленький виртуальный сервер MySQL
- Все это в Rackspace, 1 разработчик
Январь 2011
- 1 сервер nginx для балансировки нагрузки, 4 веб-сервера
- 2 сервера MySQL с master/slave репликацией
- 3 сервера для отложенного выполнения задач
- 1 сервер MongoDB
- Переехали на Amazon EC2 + S3 +
CloudFront
Осень 2011
- 2 сервера nginx, 16 веб-серверов, 2 сервера для API
- 5 функционально разделенных серверов MySQL с 9 read slave
- Кластер из 4 узлов Cassandra
- 15 серверов Membase в 3 отдельных кластерах
- 8 серверов memcached
- 10 серверов Redis
- 7 серверов для отложенной обработки задач
- 4 сервера Elastic Search
- 3 кластера MongoDB
- 3 разработчика
- Если кто-то может объяснить зачем им сдался такой зоопарк, кроме как
потестировать разные варианты, можете взять с полки пирожок.
Зима 2011-2012
- Заменили CloudFront на Akamai — вполне объяснимо,
так как у Akamai намного лучше покрытие по миру, а
качественный CDN для сайта с большим количеством
изображений — чуть ли не залог успеха. - 90 веб серверов и 50 серверов для API
- 66 + 66 MySQL серверов на m1.xlarge инстансах EC2
- 59 серверов Redis
- 51 серверов memcached
- 25+1 сервер для отложенной обработки задач на основе Redis
- Кластеризованный Solr
- 6 разработчиков
Весна-лето 2012
- Снова сменили CDN, на этот раз в пользу ранее неизвестного мне Edge
Cast. Покрытие по всему миру довольно скромное,
так что единственное логичное объяснение, которое мне приходит в
голову — не потянули Akamai по деньгам. - 135 веб серверов и 75 серверов для API
- 80 + 80 серверов MySQL
- 110 серверов Redis
- 60 серверов memcached
- 60 + 2 сервера для отложенной обработки задач на основе Redis
- 25 разработчиков
Выбор
Почему Amazon Ec2/S3?
- Очень хорошая надежность, отчетность и поддержка
- Хорошие дополнительные сервисы: кэш, базы данных, балансировка
нагрузки, MapReduce и т.п. - Новые виртуальные машины готовы за считанные секунды
Почему MySQL?
- Очень «зрелая», хорошо известная и любимая многими
- Редки катастрофичные потери данных
- Линейная зависимость времени отклика от частоты запросов
- Хорошая поддержка сторонним ПО (XtraBackup, Innotop, Maatkit)
- Надежное активное сообщество
- Отличная поддержка от Percona
- Бесплатна
Почему memcached?
- Очень «зрелый», отличная производительность, хорошо известный и
любимый многими - Никогда не ломается
- Бесплатен
Почему Redis?
- Много удобных структур данных
- Поддержка персистентности и репликации
- Также многим известен и нравится
- Стабильно хорошая производительность и надежность
- Также бесплатен
Архитектура
Сlustering vs Sharding
- Большую часть презентации, на основе которой написана данная статья
(ссылка,
если не охота листать до секции источников информации), занимает
раздел под названием «Clustering vs Sharding». В связи с путаницей в
терминологии пришлось несколько раз перечитывать, чтобы понять к
чему они клонят, сейчас попробую объяснить. - Вообще есть два фундаментальных способа распределить данные между
несколькими серверами:- Вертикально: разные таблицы (или просто логически разные
типы данных) разносятся на разные сервера. - Горизонтально: каждая таблица разбивается на некоторое
количество частей и эти части разносятся на разные сервера по
определенному алгоритму.
- Вертикально: разные таблицы (или просто логически разные
- С первого взгляда казалось, что они пытаются вертикальное разбиение
назвать sharding, а горизонтальное — clustering. Хотя вообще они
почти синонимы и на русский я их обычно примерно одинаково перевожу. - По факту же оказалось, что под словом clustering они понимают все
программные продукты для хранения данных, которые имеют встроенную
поддержку работы в кластере. В частности они имеют ввиду
Cassandra, Membase,
HBase и Riak, которые прозрачно для
пользователя горизонтально распределяют данные по кластеру. - За словом sharding в их терминологии стоит аналогичная схема
собственной разработки, использующая огромное количество логических
БД в MySQL, распределенных между меньшим количествомфизических сервероввиртуальных машин. Именно по этому пути и пошли в
Pinterest, плюс очень похожий подход используется в
Facebook. - От себя добавлю, что хоть при наличии должных ресурсов разработка
собственной системы распределения данных и может быть
целесообразной, в большинстве случаев на начальном этапе проще
основываться на готовых решениях вроде перечисленных выше. К слову в
opensource доступны и основанные на MySQL подобные решения: - В их проекте данная подсистема развивалась следующим образом:
- 1 БД + внешние ключи + join’ы →
- 1 БД + денормализация + кэш →
- 1 БД + master/slave + кэш →
- несколько функциональных разделенных БД + master/slave + кэш →
- вертикально и горизонтально разделенные БД (по
идентификаторам) + по резервные БД (пассивный slave) + кэш
- При использовании аналогичного решения остерегайтесь:
- Невозможности выполнять большинство запросов с join
- Отсутствия транзакций
- Дополнительных манипуляций для поддержания ограничений
уникальности - Необходимости тщательного планирования для изменений схемы
- Необходимости выполнения одного и того же запроса с последующей
агрегацией для построения отчетов
Остальные моменты
- Кэширование многоуровневое:
- Коллекции объектов хранятся в списках Redis
- Сами объекты — в memcached
- На уровне SQL запросы в основном примитивны и написаны вручную,
так что часты попадания в кэш MySQL - Кэш файловой системы — само собой
- Еще пара фактов про кэширование в Pinterest:
- Кэш разбит также на несколько частей (шардов), для упрощения
обслуживания и масштабирования - В коде для кэширования используются Python’овские декораторы, на
вид собственной разработки, хотя точно не уверен
- Кэш разбит также на несколько частей (шардов), для упрощения
- Балансировка нагрузки осуществляется в первую очередь за счет Amazon
ELB, что позволяет легко подключать/отключать новые сервера
посредством API. - Так как большинство пользователей живут в США по ночам нагрузка
сильно падает, что позволяет им по ночам отключать до 40%
виртуальных машин. В пиковые часы EC2 обходится порядка 52$ в час,
а по ночам — всего 15$. - Elastic Map Reduce, основанный на Hadoop, используется для анализа
данных и стоит всего несколько сотен долларов в месяц - Текущие проблемы:
- Масштабирование команды
- Основанная на сервисах архитектура:
- Ограничения соединений
- Изоляция функционала
- Изоляция доступа (безопасность)
Уроки от команды Pinterest
- «Оно сломается. Все должно быть просто.» — столько раз уже слышу
это наставление, но ни разу не видел разработчиков, которые реально
к нему прислушивались. - «Кластеризация — страшная штука.» — конечно страшная, большая и
сложная. Но кому сейчас легко? - «Продолжайте получать удовольствие.» — с этим не могу не
согласиться, без удовольствия работать совершенно невозможно в любой
сфере.
Источники информации
- Scaling Pinterest @ MySQL Meetup
- В презентации можно посмотреть примеры кода и SQL-запросов
- Если кто-то знает где можно посмотреть/послушать запись этого
мероприятия — поделитесь ссылкой, пожалуйста
- Pinterest Architecture Update
- Вакансии в Pinterest
Источник: Архитектура Pinterest