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

20 октября 2010 37 комментариев Иван Блинков

Facebook LogoНа сегодняшний день Facebook является пожалуй самым обсуждаемым интернет-проектом во всем мире. Не смотря на довольно низкий уровень проникновения Facebook в России, темпы захвата аудитории этим проектом мягко говоря поражают. Как же им удается управляться с таким огромным социальным графом и удовлетворять потребности в общении невероятно большого количества людей по всему миру?

Платформа

  • Linux — операционная система
  • PHP с HipHop — код на PHP компилируется в C++
  • memcached — агрессивное кэширование объектов
  • MySQL — используется как хранилище пар ключ-значение, никаких join'ов
  • Thrift — интерфейс взаимодействия между сервисами, написанными на разных языках программирования
  • Scribe — универсальная система сбора и агрегации данных с рабочих серверов

Статистика

  • Более 500 миллионов активных пользователей (месячная аудитория)
  • Более миллиарда социальных связей
  • Более 200 миллиардов просмотров страниц в месяц
  • Более 4 триллионов действий попадает в новостные ленты каждый день
  • Более 150 миллионов обращений к кэшу в секунду; 2 триллиона объектов в кэше
  • Более 8 миллиардов минут провели пользователи на Facebook'е ежедневно
  • Более 3 миллиардов фотографий загружается каждый месяц, до 1.2 миллиона фотографий в секунду
  • 20 миллиардов фотографий в 4 разрешениях = 80 миллиардов фотографий, их бы хватило чтобы покрыть поверхность земли в 10 слоев; это больше, чем на всех других фото-ресурсах в месте взятых
  • О более чем 5 миллиардах единиц контента рассказывается друзьям еженедельно
  • Более миллиарда сообщений в чате каждый день
  • Более ста миллионов поисковых запросов в день
  • Более 250 приложений и 80 тысяч сторонних ресурсов на платформе Facebook Connect
  • Более 400 тысяч разработчиков сторонних приложений
  • Менее 500 разработчиков и системных администраторов в штате
  • Более миллиона активных пользователей на одного инженера
  • Десятки тысяч серверов, десятки гигабит трафика

Архитектура

Общие принципы

  • Балансировщик нагрузки выбирает веб-сервер для обработки запроса
  • PHP-код в веб-сервере подготавливает HTML, пользуясь данными из различных источников:
    • MySQL
    • memcached
    • Специализированные сервисы
  • Если взглянуть с другой стороны, то получим трехуровневую архитектуру:
    • Вер-приложение
    • Распределенный индекс
    • Постоянное хранилище
  • Использование открытых технологий там, где это возможно
  • Поиск возможностей оптимизации используемых продуктов
  • Философия Unix:
    • Старайтесь делать каждый компонент системы простым и производительным
    • Комбинируйте компоненты для решения задач
    • Концентрируйте внимание на хорошо обозначенных точках взаимодействия
  • Все усилия направлены на масштабируемость
  • Попытки минимизации количества точек отказа
  • Простота, простота, простота!

PHP

Почему PHP?

  • Во многом «так исторически сложилось»
  • Хорошо подходит для веб-разработки
  • Легок в изучении: небольшой набор выражений и языковых конструкций
  • Легок в написании: нестрогая типизация и универсальный «массив»
  • Легок в чтении: синтаксис похож на C++ и Java
  • Прост в дебаггинге: нет необходимости в перекомпиляции
  • Большой ассортимент библиотек, актуальных для веб-проектов
  • Подходит для процесса разработки с короткими итерациями
  • Активное сообщество разработчиков по всему миру
  • Динамическая типизация, интерпретируемый язык для скриптов

Как оказалось на самом деле?

  • Высокий расход оперативной памяти и вычислительных ресурсов
  • Сложно работать, когда объем исходного кода очень велик: слабая типизация и ограниченные возможности для статичного анализа и оптимизации кода
  • Не особо оптимизирован для использования в крупных проектах
  • Линейный рост издержек при подключении файлов с исходным кодом
  • Механизм разработки расширений не очень удобен

Доработки:

  • Оптимизация байт-кода
  • Улучшения в APC (ленивая загрузка, оптимизация блокировок, «подогрев» кэша)
  • Свои расширения (клиент memcache, формат сериализации, логи, статистика, мониторинг, механизм асинхронной обработки событий)
  • HipHop — трансформатор исходных кодов:
    • Разработчики пишут на PHP, который конвертируется в оптимизированный C++
    • Статический анализ, определение типов данных, генерация кода, и.т.д.
    • Облегчает разработку расширений
    • Существенно сокращает расходы оперативной памяти и вычислительных ресурсов
    • У команды из трех программистов ушло полтора года на разработку, переписаны большая часть интерпретатора и многие расширения языка
    • Опубликован под opensource лицензией в начале года, нет необходимости проходить этот же путь с нуля

MySQL

Как используется MySQL?

  • Используется как хранилище пар ключ-значение
  • Большое количество логических узлов распределено между физическими машинами
  • Балансировка нагрузке на уровне физических серверов
  • Репликация для распределения операций чтения не используется
  • Большинство запросов касаются самой свежей информации: оптимизация таблиц для доступа к новым данным, архивация старых записей
  • В целом быстро и надежно

Как оказалось на самом деле?

  • Логическая миграция данных очень сложна
  • Создавать большое количество логических баз данных и перераспределять их между физическими узлами, балансируя таким образом нагрузку, намного удобнее
  • Никаких join'ов на рабочих серверах баз данных
  • Намного проще наращивать вычислительные мощности на веб-серверах, чем на серверах баз данных
  • Схемы, основанные на структуре данных, делают программистов счастливыми и создают большую головную боль администраторам
  • Никогда не храните не-статичные данные в централизованное базе данных

Доработки:

  • Практически никаких модификаций исходного кода MySQL
  • Своя схема партиционирования с глобально-уникальными идентификаторами
  • Своя схема архивирования, основанная на частоте доступа к данным относительно каждого пользователя
  • Расширенный движок запросов для репликации между датацентрами и поддержания консистенции кеша
  • Библиотеки для доступа к данным на основе графа:
    • Объекты (вершины графа) с ограниченными типами данных (целое число, строка ограниченно длины, текст)
    • Реплицированные связи (ребра графа)
    • Аналоги распределенных внешних ключей (foreign keys)
    • Большинство данных распределено случайно

Memcache

Как используется memcached?

  • Высокопроизводительная распределенная хэш-таблица
  • Содержит «горячие» данные из MySQL
  • Снижает нагрузку на уровень баз данных
  • Основная форма кэширования
  • Используется более 25TB памяти на нескольких тысячах серверов
  • Среднее время отклика менее 250 микро-секунд
  • Кэшируются сериализованные структуры данных PHP
  • Отсутствие автоматического механизма проверки консистенции данных между memcached и MySQL — приходится делать это на уровне программного кода
  • Множество multi-get запросов для получения данных на другом конце ребер графа
  • Ограниченная модель данных, неэффективен для маленьких объектов

Доработки:

  • Порт на 64-битную архитектуру
  • Более эффективная сериализация
  • Многопоточность
  • Улучшенный протокол
  • Компрессия
  • Проксирование запросов
  • Доступ к memcache через UDP:
    • уменьшает расход памяти благодаря отсутствию тысяч буферов TCP соединений
    • управление ходом исполнения приложение (оптимизация для multi-get)
  • Статистика о работе потоков по запросу — уменьшает блокировки
  • Ряд изменений в ядре Linux для оптимизации работы memcache:
    • распределение управления сетевыми прерывания по всем ядрам
    • оппортунистический опрос сетевых интерфейсов
  • После вышеперечисленных модификаций memcached способен выполнять до 250 тысяч операций в секунду, по сравнению со стандартными 30-40 тысячами без данных изменений

Thrift

Что это?

  • Легкий механизм построения приложений с использованием нескольких языков программирования
  • Высокая цель: предоставить механизм прозрачного взаимодействия между языками программирования.
  • Предоставляет язык описания интерфейсов, статический генератор кода
  • Поддерживаемые языки: C++, PHP, Python, Java, Ruby, Erlang, Perl, Haskell и многие другие
  • Транспорты: простой интерфейс для ввода-вывода (сокеты, файлы, буферы в памяти)
  • Протоколы: стандарты сериализации (бинарный, JSON)
  • Серверы: неблокирующие, асинхронные, как однопоточные, так и многопоточные

Почему именно Thrift?

  • Альтернативные технологии: SOAP, CORBA, COM, Pillar, Protocol Buffers — но у всех есть свои существенные недостатки, что вынудило Facebook создать свою технологию
  • Он быстрый, очень быстрый
  • Меньше рабочего времени тратится каждым разработчиком на сетевые интерфейсы и протоколы
  • Разделение труда: работа над высокопроизводительными серверами ведется отдельно от работы над приложениями
  • Общий инструментарий, знакомый всем разработчикам

Scribe

Что это?

  • Масштабированный распределенный механизм ведения логов
  • Перемещает данные с серверов в центральный репозиторий
  • Широкая сфера применения:
    • Логи поисковых запросов
    • Публикации в новостных лентах
    • Данные по A/B тестированиям
  • Более надежен, чем традиционные системы логгирования, но недостаточно надежен для транзакций баз данных
  • Простая модель данных
  • Построен на основе Thrift

Хранение фотографий

Сначала сделали это просто:

  • Загрузка на сервер: приложение принимает изображение, создает миниатюры в нужных разрешениях, сохраняет в NFS
  • Загрузка с сервера: изображения отдаются из NFS через HTTP
  • NFS построена на коммерческих продуктах
  • Это было необходимо, чтобы сначала проверить, что продукт востребован пользователями и они правда будут активно загружать фотографии
  • На самом деле оказалось, что:
    • Файловые системы непригодны для работы с большим количеством небольших файлов
    • Метаданные не помещаются в оперативную память, что приводит к дополнительным обращениям к дисковой подсистеме
    • Ограничивающим фактором является ввод-вывод, а не плотность хранения

Потом начали оптимизировать:

  • Кэширование более часто используемых миниатюр изображений в памяти на оригинальных серверах для масштабируемости, надежности и производительности
  • Распределение их по CDN для уменьшения сетевых задержек
  • Возможно сделать еще лучше:
    • Хранение изображений в больших бинарных файлах (blob)
    • Сервис, отвечающий за фотографии имеет информацию о том, в каком файле и с каким отступом от начала расположена каждая фотография (по ее идентификатору)
    • Этот сервис в Facebook называется Haystack и он оказался в 10 раз эффективнее «простого» подхода и в 3 раза эффективнее «оптимизированного»

Другие сервисы

  • SMC: консоль управления сервисами — централизованная конфигурация, определение на какой физической машине работает логический сервис
  • ODS:  инструмент для визуализации изменений любых статистических данных, имеющихся в системе; удобен для мониторинга и оповещений
  • Gatekeeper: разделение развертывания и запуска, A/B тестирования, таргетированный запуск, постепенный запуск
  • И еще около 50 других сервисов…

Как это работает все вместе?

Новые альбомы друзей

Facebook Screenshot

  1. Получаем профиль по идентификатору пользователя (скорее всего из кэша, но потенциально возможно обращение к базе данных)
  2. Получаем список друзей (опять же на основе идентификатора пользователя из кэша или из базы данных в случае промаха)
  3. Параллельно запрашиваем идентификаторы последних 10 альбомов для каждого из друзей (multi-get, каждый промах мимо кэша индивидуально вытаскивается из MySQL)
  4. Параллельно получаем данные о всех альбомах (на основе идентификаторов альбомов из предыдущего шага)
  5. Все данные получены, выполняем логику отрисовки конкретной страницы на PHP
  6. Отправляем HTML в браузер, пользователь счастлив :)

Новостная лента

News Feed Screenshot

News Feed Scheme

Поиск

Search Screenshot

Search Scheme

Подводим итоги

LAMP не идеален

  • PHP+MySQL+Memcache решает большинство задач, но не может решить совсем все:
    • PHP не может хранить состояния
    • PHP не самый производительный язык
    • Все данные находятся удаленно
  • Facebook разрабатывает собственные внутренние сервисы, чтобы:
    • Располагать исполняемый код ближе к данным
    • Скомпилированное окружение более эффективно
    • Некоторая функциональность присутствует только в других языках программирования
  • Философия сервисов:
    • Создание сервисов только при необходимости (минимизация издержек по развертке, поддержке и ведению отдельной кодовой базы; потенциальная дополнительная точка сбоя)
    • Создание общего набора инструментов для создания сервисов (Thrift, Scribe, ODS, средства мониторинга и уведомлений)
    • Использование правильных языка программирования, библиотек и инструментов для решения задачи
  • Возвращение инноваций общественности — важный аспект разработки в Facebook:
    • Опубликованные свои проекты:
      • Thrift
      • Scribe
      • Tornado
      • Cassandra
      • Varnish
      • Hive
      • xhprof
    • Доработки популярных решений:
      • PHP
      • MySQL
      • memcached
    • Информация о взаимодействии Facebook с opensource-сообществом, этих и других проектах расположена на странице, посвященной opensource.
  • Ключевые моменты культуры разработки в Facebook:
    • Двигайся быстро и не бойся ломать некоторые вещи
    • Большое влияние маленьких команд
    • Будь откровенным и инновационным

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

Данная статья не является переводом готовой статьи, в качестве источников информации послужили записи выступлений сотрудников Facebook на конференциях:

Очень рекомендую посмотреть материалы в оригинале, так как естественно я осветил в статье далеко не все, да и неточности какие-либо неисключены. Помимо этого возможно многим будет интересно мероприятие «Facebook: how we scaled to 500 000 000 users «, где Robert Johnson выступает 22 октября в Москве. Еще он числится в списке докладчиков Highload++ с аналогичным выступлением. Дополнительную информацию можно почерпнуть в блоге инженеров Facebook.

UPD: Обновил некоторые моменты после посещения вышеупомянутого выступления Роберта.

И по традиции напоминаю, что так как я пишу довольно редко — читать мой блог намного удобнее по RSS. Спасибо за внимание :)

Метки: , , , , , , , , , , ,

  • http://neoscrum.com Денис Миллер

    С возвращением к архитектурным заметкам! :)

    Спасибо, что добавляешь источники информации. После хорошего обзора уже не страшно и оригиналы смотреть :)

  • http://gnu.su/ AndreikA

    Спасибо, красота!

  • http://onjs.net Stark

    Спасибо, как всегда было интересно и полезно почитать :)

  • nike-bl

    Спасибо за еще один хороший обзор!

  • http://blog.shyshov.com Владимир

    Классный обзор, очень просто, лаконично и понятно, спасибо!

  • http://seriyps.ru/ Сергей

    Эх фейсбук... Костыль на костыле)

  • http://restoranam.net Dr.Death

    Кое-что интересно

  • Sergey

    >инжинера

    инженера

  • http://www.vbrauzere.ru rkt

    я конечно в базах не силен, не думал что фейсбук может сидеть в MySQL

  • Andrew

    cassandra.apache.org

    Cassandra is in use at Digg, Facebook, Twitter, Reddit, Rackspace, Cloudkick, Cisco, SimpleGeo, Ooyala, OpenX, and more companies that have large, active data sets. The largest production cluster has over 100 TB of data in over 150 machines...

    В статье не слова об этом.

    Почему PHP?

    — Легок в написании: нестрогая типизация и универсальный «массив»

    — Динамическая типизация, интерпретируемый язык для скриптов

    тавтология какая-то...

    Низачот статье.

  • Сергей

    1.2 миллиона фотографий в секунду

    если учесть, что 3 миллиарда в месяц, то здесь явно грубая ошибка:)

  • anmi

    # 20 миллиардов фотографий в 4 разрешениях = 80 миллиардов фотографий, их бы хватило чтобы покрыть поверхность земли в 10 слоев; это больше, чем на всех других фото-ресурсах в месте взятых

    площадь земли 5,1*10**14

    ничего не перепутали?

    средний размер фотографии 6374 кв. м. что-ли?

  • Wicked

    anmi, при dpi чуть больше нуля все ок :)

  • Pingback: Phil Kulin (schors) - Juick

  • http://nofate.name Nofate

    Жаль, что в статье нет подробностей об использовании NoSQL базы данных Cassandra.

  • http://www.insight-it.ru Иван Блинков

    Извиняюсь за отсутствие фидбека - сегодня весь день был на RIW2010, где был невероятно несправляющийся с нагрузкой WiFi.

    Тем временем тут хабраэффект случился и за сегодня аж 15 тысяч просмотров у блога :)

    Всем огромное спасибо за отзывы, очень приятно, кое на что могу даже ответить:

    — Про Cassandra я на самом деле думал отдельную статью попробовать написать, в этом посте только кратко заикнулся; если кому-то охота подробностей — ссылки на источники я привел: там тоже совсем чуть-чуть о ней говорили, используется в каком-то одном сервисе, то ли обмена сообщениями, то ли еще что-то в этом духе (по памяти пишу, могу ошибаться).

    — Про фотографии собственно говоря за что купил, за то и продаю — цифра в секунду скорее всего пиковая, а площадь да, сильно зависит от dpi.

  • http://scm-notes.blogspot.com/ Aquary

    Иван, добрейшего.

    Я там на мыло список фиксов для статьи отправлял... опечатки и мелкие неточности. Но вернулось ведолмление, что переадресация на адрес наличном домене не прошла.

    Страшно волнуюсь о судьбе письма! Вдруг не дошло, сгинуло... :)

  • http://blog.fuzaylov.net Fuzaylov

    Как раз работаю над проектом который будет прилично нагружаться! Эти сведения мне помогут в работе! Спасибо большое!

  • Pingback: Facebook: how we scaled to 500 000 000 users by Robert Johnson | Insight IT

  • multik

    Отличная статья, спасибо.

  • Pingback: #highload » TygerSpace

  • Pingback: Архитектура Вконтакте « Блог креативного мышления

  • Pingback: Бложек Падлы» Архив сайта » Архитектура Вконтакте

  • http://www.vladevdokimov.ru Влад

    Отличный репортаж.

    Почитал с удовольствием.

    Надеюсь не будете против что перепостил у себя www.vladevdokimov.ru/blog/programing/187.html

    Еще раз спасибо!

  • http://www.insight-it.ru Иван Блинков

    Влад, конечно не против — обратная ссылка на оригинал есть, чего мне еще желать? :)

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

  • Pingback: Архитектура Facebook | Денис 'rez0n' Вербин

  • http://www.joker-pro.com Маша

    Классный Обзор(с большой Буквы!) Спасибо, с наступившим НГ!

  • Pingback: Архитектура Mollom | My Blog

  • Pingback: Facebook за 20 минут | My Blog

  • Pingback: Архитектура Mollom | My Blog

  • Pingback: from twitter 2011-03-16 – 2011-03-16 | Архив twitter.com/404666

  • Bloknot

    Площадь поверхности ВСЕЙ земли 5.1*10^14 (М2).

    При этом если учесть что с «большим запасом» средняя площадь одной фотографии равна 1м2, то для покрытия всей земли хотябы в 1 слой потребовалосьбы ПолМиллиона Миллиардов фотографий, что в 6000 раз больше чем в приведенной статистике.

    Но думаеццо, что это не заГорами!

  • http://juravskiy.ru Vitaliy

    У них 160 + серверов с Apache Cassandra

  • Roma

    Статья полностью содрана с журнала Хакер

    • http://www.insight-it.ru Ivan Blinkov

      Наоборот, сравни даты и посмотри на автора статьи в Хакере :)

  • Roma

    Статья полностью содрана с журнала Хакер

  • Pingback: Архитектура Tumblr | Insight IT