Вопрос Как устроены Facebook и Vkontakte
«Facebook» — социальная сеть, основанная в 2004 году Марком Цукербергом и его соседями по комнате во время обучения в Гарвардском университете Эдуардо Саверином, Дастином Московицем и Крисом Хьюзом. Благодаря своему сайту Марк Цукерберг стал самым молодым миллиардером в свои 23 года.
Первоначально веб-сайт был назван thefacebook.com (позже изменён на современный вариант facebook) и открыт только для студентов Гарвардского Университета, затем доступ был расширен для других университетов Бостона, а затем и для студентов любых учебных учреждений США, имеющих электронный адрес с доменом .edu. Начиная с сентября 2006 года сайт был открыт для всех пользователей в возрасте от 13 лет, имеющих электронную почту. По состоянию на 21 июля 2010 года Facebook насчитывает более 500 миллионов пользователей по всему миру. При этом количество уникальных посетителей сайта в апреле 2010 года составило 540 млн, а количество просмотров страниц — 570 млрд. Прибыль Facebook за 2009 год по собственной оценке компании составила 700 млн долларов США.
Платформа * 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, пользуясь данными из различных источников: o MySQL o memcached o Специализированные сервисы * Если взглянуть с другой стороны, то получим трехуровневую архитектуру: o Вер-приложение o Распределенный индекс o Постоянное хранилище * Использование открытых технологий там, где это возможно * Поиск возможностей оптимизации используемых продуктов * Философия Unix: o Старайтесь делать каждый компонент системы простым и производительным o Комбинируйте компоненты для решения задач o Концентрируйте внимание на хорошо обозначенных точках взаимодействия * Все усилия направлены на масштабируемость * Попытки минимизации количества точек отказа * Простота.
* Во многом «так исторически сложилось» * Хорошо подходит для веб-разработки * Легок в изучении: небольшой набор выражений и языковых конструкций * Легок в написании: нестрогая типизация и универсальный «массив» * Легок в чтении: синтаксис похож на C++ и Java * Прост в дебаггинге: нет необходимости в перекомпиляции * Большой ассортимент библиотек, актуальных для веб-проектов * Подходит для процесса разработки с короткими итерациями * Активное сообщество разработчиков по всему миру * Динамическая типизация, интерпретируемый язык для скриптов
Как оказалось на самом деле?
* Высокий расход оперативной памяти и вычислительных ресурсов * Сложно работать, когда объем исходного кода очень велик: слабая типизация и ограниченные возможности для статичного анализа и оптимизации кода * Не особо оптимизирован для использования в крупных проектах * Линейный рост издержек при подключении файлов с исходным кодом * Механизм разработки расширений не очень удобен
* Оптимизация байт-кода * Улучшения в APC (ленивая загрузка, оптимизация блокировок, «подогрев» кэша) * Свои расширения (клиент memcache, формат сериализации, логи, статистика, мониторинг, механизм асинхронной обработки событий) * HipHop — трансформатор исходных кодов: o Разработчики пишут на PHP, который конвертируется в оптимизированный C++ o Статический анализ, определение типов данных, генерация кода, и.т.д. o Облегчает разработку расширений o Существенно сокращает расходы оперативной памяти и вычислительных ресурсов o У команды из трех программистов ушло полтора года на разработку, переписаны большая часть интерпретатора и многие расширения языка o Опубликован под opensource лицензией в начале года, нет необходимости проходить этот же путь с нуля
Как используется MySQL?
* Используется как хранилище пар ключ-значение * Большое количество логических узлов распределено между физическими машинами * Балансировка нагрузке на уровне физических серверов * Репликация для распределения операций чтения не используется * Большинство запросов касаются самой свежей информации: оптимизация таблиц для доступа к новым данным, архивация старых записей * В целом быстро и надежно
Как оказалось на самом деле?
* Логическая миграция данных очень сложна * Создавать большое количество логических баз данных и перераспределять их между физическими узлами, балансируя таким образом нагрузку, намного удобнее * Никаких join'ов на рабочих серверах баз данных * Намного проще наращивать вычислительные мощности на веб-серверах, чем на серверах баз данных * Схемы, основанные на структуре данных, делают программистов счастливыми и создают большую головную боль администраторам * Никогда не храните не-статичные данные в централизованное базе данных
* Практически никаких модификаций исходного кода MySQL * Своя схема партиционирования с глобально-уникальными идентификаторами * Своя схема архивирования, основанная на частоте доступа к данным относительно каждого пользователя * Расширенный движок запросов для репликации между датацентрами и поддержания консистенции кеша * Библиотеки для доступа к данным на основе графа: o Объекты (вершины графа) с ограниченными типами данных (целое число, строка ограниченно длины, текст) o Реплицированные связи (ребра графа) o Аналоги распределенных внешних ключей (foreign keys) o Большинство данных распределено случайно
Как используется memcached?
* Высокопроизводительная распределенная хэш-таблица * Содержит «горячие» данные из MySQL * Снижает нагрузку на уровень баз данных * Основная форма кэширования * Используется более 25TB памяти на нескольких тысячах серверов * Среднее время отклика менее 250 микро-секунд * Кэшируются сериализованные структуры данных PHP * Отсутствие автоматического механизма проверки консистенции данных между memcached и MySQL — приходится делать это на уровне программного кода * Множество multi-get запросов для получения данных на другом конце ребер графа * Ограниченная модель данных, неэффективен для маленьких объектов
* Порт на 64-битную архитектуру * Более эффективная сериализация * Многопоточность * Улучшенный протокол * Компрессия * Проксирование запросов * Доступ к memcache через UDP: o уменьшает расход памяти благодаря отсутствию тысяч буферов TCP соединений o управление ходом исполнения приложение (оптимизация для multi-get) * Статистика о работе потоков по запросу — уменьшает блокировки * Ряд изменений в ядре Linux для оптимизации работы memcache: o распределение управления сетевыми прерывания по всем ядрам o оппортунистический опрос сетевых интерфейсов * После вышеперечисленных модификаций memcached способен выполнять до 250 тысяч операций в секунду, по сравнению со стандартными 30-40 тысячами без данных изменений
* Легкий механизм построения приложений с использованием нескольких языков программирования * Высокая цель: предоставить механизм прозрачного взаимодействия между языками программирования. * Предоставляет язык описания интерфейсов, статический генератор кода * Поддерживаемые языки: C++, PHP, Python, Java, Ruby, Erlang, Perl, Haskell и многие другие * Транспорты: простой интерфейс для ввода-вывода (сокеты, файлы, буферы в памяти) * Протоколы: стандарты сериализации (бинарный, JSON) * Серверы: неблокирующие, асинхронные, как однопоточные, так и многопоточные Почему именно Thrift?
* Альтернативные технологии: SOAP, CORBA, COM, Pillar, Protocol Buffers — но у всех есть свои существенные недостатки, что вынудило Facebook создать свою технологию * Он быстрый, очень быстрый * Меньше рабочего времени тратится каждым разработчиком на сетевые интерфейсы и протоколы * Разделение труда: работа над высокопроизводительными серверами ведется отдельно от работы над приложениями * Общий инструментарий, знакомый всем разработчикам
* Масштабированный распределенный механизм ведения логов * Перемещает данные с серверов в центральный репозиторий * Широкая сфера применения: o Логи поисковых запросов o Публикации в новостных лентах o Данные по A/B тестированиям * Более надежен, чем традиционные системы логгирования, но недостаточно надежен для транзакций баз данных * Простая модель данных * Построен на основе Thrift
Хранение фотографий
Сначала сделали это просто:
* Загрузка на сервер: приложение принимает изображение, создает миниатюры в нужных разрешениях, сохраняет в NFS * Загрузка с сервера: изображения отдаются из NFS через HTTP * NFS построена на коммерческих продуктах * Это было необходимо, чтобы сначала проверить, что продукт востребован пользователями и они правда будут активно загружать фотографии * На самом деле оказалось, что: o Файловые системы непригодны для работы с большим количеством небольших файлов o Метаданные не помещаются в оперативную память, что приводит к дополнительным обращениям к дисковой подсистеме o Ограничивающим фактором является ввод-вывод, а не плотность хранения
Потом начали оптимизировать:
* Кэширование более часто используемых миниатюр изображений в памяти на оригинальных серверах для масштабируемости, надежности и производительности * Распределение их по CDN для уменьшения сетевых задержек * Возможно сделать еще лучше: o Хранение изображений в больших бинарных файлах (blob) o Сервис, отвечающий за фотографии имеет информацию о том, в каком файле и с каким отступом от начала расположена каждая фотография (по ее идентификатору) o Этот сервис в Facebook называется Haystack и он оказался в 10 раз эффективнее «простого» подхода и в 3 раза эффективнее «оптимизированного» Другие сервисы
* SMC: консоль управления сервисами — централизованная конфигурация, определение на какой физической машине работает логический сервис * ODS: инструмент для визуализации изменений любых статистических данных, имеющихся в системе; удобен для мониторинга и оповещений * Gatekeeper: разделение развертывания и запуска, A/B тестирования, таргетированный запуск, постепенный запуск * И еще около 50 других сервисов.
В Контакте — крупнейшая в Рунете социальная сеть, российский аналог сервиса Facebook. По данным Alexa Internet - второй по посещаемости сайт России, второй на Украине и в Белоруссии, четвёртый в Казахстане, 34-й в мире. Сайт изначально позиционировал себя в качестве социальной сети студентов и выпускников элитных российских высших учебных заведений, позднее — как универсальный способ связи для всех социальных групп и возрастов. В январе 2009 года «В Контакте» впервые обогнал по посещаемости в России своего главного конкурента — «Одноклассники». А уже в апреле на сайт «В Контакте» зашло 14,3 миллиона уникальных российских пользователей, тогда как на «Одноклассники» — 7,8 миллиона, что почти в 2 раза меньше.
* Debian Linux — основная операционная система * nginx — балансировка нагрузки * PHP + XCache * Apache + mod_php * memcached * MySQL * Собственная СУБД на C * node.js — прослойка для реализации XMPP, живет за HAProxy * Изображения отдаются просто с файловой системы xfs * ffmpeg — конвертирование видео
* 95 миллионов учетных записей * 40 миллионов активных пользователей во всем мире (сопоставимо с аудиторией интернета в России) * 11 миллиардов запросов в день * 200 миллионов личных сообщений в день * Видеопоток достигает 160Гбит/с * Более 10 тысяч серверов, из которых только 32 — фронтенды на nginx (количество серверов с Apache неизвестно) * 30-40 разработчиков, 2 дизайнера, 5 системных администраторов, много людей в датацентрах * Каждый день выходит из строя около 10 жестких дисков
Архитектура
* Cервера многофункциональны и используются одновременно в нескольких ролях: o Перебрасывание полуавтоматическое o Требуется перезапускать daemon'ы * Генерация страниц с новостями (микроблоги) происходит очень похожим образом с Facebook (см. Архитектура Facebook), основное отличие — использование собственной СУБД вместо MySQL * При балансировке нагрузки используются: o Взвешенный round robin внутри системы o Разные сервера для разных типов запросов o Балансировка на уровне ДНС на 32 IP-адреса * Большая часть внутреннего софта написано самостоятельно, в том числе: o Собственная СУБД (см. ниже) o Мониторинг с уведомлением по СМС (Павел сам помогал верстать интерфейс ) o Автоматическая система тестирования кода o Анализаторы статистики и логов * Мощные сервера: o 8-ядерные процессоры Intel (по два на сервер, видимо) o 64Гб оперативной памяти o 8 жестких дисков (соответственно скорее всего корпуса 2-3U) o RAID не используется o Не брендированные, собирает компания ТехноОкта * Вычислительные мощности серверов используются менее, чем на 20% * Сейчас проект расположен в 4 датацентрах в Санкт-Петербурге и Москве, причем: o Вся основная база данных располагается в одном датацентре в Санкт-Петербурге o В Московских датацентрах только аудио и видео o В планах сделать репликацию базы данных в другой датацентр в ленинградской области * CDN на данный момент не используется, но в планах есть * Резервное копирование данных происходит ежедневно и инкрементально
База данных на C
Этому продукту, пожалуй, уделялось максимум внимания аудитории, но при этом почти никаких подробностей о том, что он, собственно говоря, собой представляет, так и не было обнародовано. Известно, что:
* Разработана «лучшими умами» России: o Андрей Лопатин o Николай Дуров o Арсений Смирнов o Алексей Левин * Используется в огромном количестве сервисов: o Личные сообщения o Сообщения на стенах o Статусы o Поиск o Приватность o Списки друзей * Нереляционная модель данных * Большинство операций осуществляется в оперативной памяти * Интерфейс доступа представляет собой расширенный протокол memcached, специальным образом составленные ключи возвращают результаты сложных запросов (чаще всего специфичных для конкретного сервиса) * Хотели бы сделать из данной системы универсальную СУБД и опубликовать под GPL, но пока не получается из-за высокой степени интеграции с остальными сервисами * Кластеризация осуществляется легко * Есть репликация * Если честно, я так и не понял зачем им MySQL с такой штукой — возможно просто как legacy живет со старых времен
Аудио и видео
Эти подпроекты являются побочными для социальной сети, на них особо не фокусируются. В основном это связанно с тем, что они редко коррелируют с основной целью использования социальной сети — общением, а также создают большое количество проблем: видеотраффик — основная статья расходов проекта, плюс всем известные проблемы с нелегальным контентом и претензиями правообладателей. Медиа-файлы банятся по хэшу при удалении по просьбе правообладателей, но это неэффективно и планируется усовершенствовать этот механизм.
1000—1500 серверов используется для перекодирования видео, на них же и хранится.
Некоторое время назад появилась возможность общаться на Вконтакте через протокол Jabber (он же XMPP). Протокол совершенно открытый и существует масса opensource реализаций.
По ряду причин, среди которых проблемы с интеграцией с остальными сервисами, было решено за месяц создать собственный сервер, представляющий собой прослойку между внутренними сервисами Вконтакте и реализацией XMPP протокола. Основные особенности этого сервиса:
* Реализован на node.js (выбор обусловлен тем, что JavaScript знают практически все разработчики проекта, а также хороший набор инструментов для реализации задачи) * Работа с большими контакт-листами — у многих пользователей количество друзей на вконтакте измеряется сотнями и тысячами * Высокая активность смены статусов — люди появляются и исчезают из онлайна чаще, чем в других аналогичных ситуациях * Аватарки передаются в base64 * Тесная интеграция с внутренней системой обмена личными сообщениями Вконтакте * 60-80 тысяч человек онлайн, в пике — 150 тысяч * HAProxy обрабатывает входящие соединения и используется для балансировки нагрузки и развертывания новых версий * Данные хранятся в MySQL (думали о MongoDB, но передумали) * Сервис работает на 5 серверах разной конфигурации, на каждом из них работает код на node.js (по 4 процесса на сервер), а на трех самых мощных — еще и MySQL * В node.js большие проблемы с использованием OpenSSL, а также течет память * Группы друзей в XMPP не связаны с группами друзей на сайте — сделано по просьбе пользователей, которые не хотели чтобы их друзья из-за плеча видели в какой группе они находятся
Интеграция со внешними ресурсами
Во Вконтакте считают данное направление очень перспективным и осуществляют массу связанной с этим работы. Основные предпринятые шаги:
* Максимальная кроссбраузерность для виджетов на основе библиотек easyXDM и fastXDM * Кросс-постинг статусов в Twitter, реализованный с помощью очередей запросов * Кнопка «поделиться с друзьями», поддерживающая openGraph теги и автоматически подбирающая подходящую иллюстрацию (путем сравнивание содержимых тега <title> и атрибутов alt у изображений, чуть ли не побуквенно) * Возможность загрузки видео через сторонние видео-хостинги (YouTube, RuTube, Vimeo, и.т.д.), открыты к интеграции с другими