Архитектура Pinterest

Pinterest - по непонятным для меня причинам популярная в определенных кругах социальная сеть, построенная вокруг произвольных картинок чаще всего не собственного производства. Как и Instagram проект довольно молодой, с очень похожей историей и стеком технологий. Тем не менее, Pinterest определенно заслуживает внимания как один из самых быстрорастущих по посещаемости вебсайтов за всю историю.

Платформа

  • AmazonAWS - хостинг и вспомогательные сервисы
  • nginx - вторичная балансировка нагрузки, отдача статики
  • Python - язык программирования
  • Django - фреймворк
  • MySQL - основная СУБД
  • memcached - кэширование объектов
  • Redis - кэширование коллекций объектов
  • Solr - поиск
  • Hadoop - анализ данных

Статистика

  • 3 миллиона уникальных посетителей в день
  • 18 миллионов уникальных посетителей в месяц
  • 4-я по популярности социальная сеть в США после FacebookTwitter и 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

  1. "Оно сломается. Все должно быть просто." - столько раз уже слышу это наставление, но ни разу не видел разработчиков, которые реально к нему прислушивались.
  2. "Кластеризация - страшная штука." - конечно страшная, большая и сложная. Но кому сейчас легко?
  3. "Продолжайте получать удовольствие." - с этим не могу не согласиться, без удовольствия работать совершенно невозможно в любой сфере.

Источники информации

  • Scaling Pinterest @ MySQL Meetup
    • В презентации можно посмотреть примеры кода и SQL-запросов
    • Если кто-то знает где можно посмотреть/послушать запись этого мероприятия - поделитесь ссылкой, пожалуйста
  • Pinterest Architecture Update
  • Вакансии в Pinterest