Pinterest - по непонятным для меня причинам популярная в определенных кругах социальная сеть, построенная вокруг произвольных картинок чаще всего не собственного производства. Как и Instagram проект довольно молодой, с очень похожей историей и стеком технологий. Тем не менее, Pinterest определенно заслуживает внимания как один из самых быстрорастущих по посещаемости вебсайтов за всю историю.
Платформа
- AmazonAWS - хостинг и вспомогательные сервисы
- 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
15 августа 2012 | | Высокие нагрузки