(#1) Как устроены крупные соц.сети изнутри. Часть 1. О мифах после конференции Highload++.

Nov 16, 2010 16:10

Это вступительное слово к проводимым мастер-классам, которые дадут вам практические сведения, как на самом деле можно построить крупный горизонтально масштабируемый проект web 2.0 с нуля (самостоятельно). Вы досконально понимаете, как устроен крупные и можете воспроизвести их аналог сами? А так же комментарии о многих важных недосказанных моментах к прошедшей конференции Highload++ в октябре 2010 года.

Сожалею, в этой короткой статье, не будет ответа, как построить крупный проект. Но зато будет написано, где и каким образом получить данные сведения, а так же, на что не надо тратить время. Вы наверняка внимательно читали сайты типа insight-it. И, конечно, понимаете - это всего лишь общие слова. Такие же, как описание НЛО сотнями очевидцев. Только вот проблема: как НЛО работает и как вам лично воспроизвести тоже самое - не написано. Я попробую исправить это.

Здесь и далее речь идет о неком абстрактом проекте (соц.сеть, приложние для соц.сети, веб-магазин, СМИ, блог, FLASH игра, каталог знаний и т.д.) с 10-100 млн пользователей. Не важно, какова роль сущностей в проекте, заменяйте по ходу чтения слово “пользователь” на “товар” или “ветка обсуждения”. Не важно, на каком языке и базе данных вы это делаете, каков тип и функционал вашего проекта.


Великие заблуждения о методах создания крупных проектов web 2.0.

Эта глава не связана с конференцией. Общие сведения. С них начинается мой мастер-класс, перед тем, как плавно перейти к сути построения архитектуры соц.сети на десятки млн. пользователей. О наболевшем в кратких тезисах.

[1] Единственное, что вам нужно сделать в вашем проекте - это честное горизонтальное масштабирование (сложно в 3-х словах объяснить истинный смысл этого термина). Не важно, что проект будет частично говнокодистым и не оптимизированным - на это нет времени из-за бешеного темпа разработки... Если вы заложите правильную масштабируемость - ваш проект выдержит бурный рост.

Наш проект испытывал внезапные скачки посещаемости за сутки на +300.000 новых уникальных посетителей в сутки (до 1.150.000). Естественно, не все было идеально, притормаживало, но работало. У нас много кривых мест, но работает все благодаря только одному - архитектуре, позволяющей на лету масштабироваться. Обычный проект никакого роста не выдержит - ляжет до тех пор, пока не схлынет волна пользователей, которые больше не вернутся. И ваш стартап - труп навеки.

[2] Highload - это заезжанное слово, которые все лепят там и тут. См. пункт 1. Чуть ли не домашнюю страничку Васи Пупкина называют хайлодом. Отучайтесь использовать слова типа “инновационный” и “нано”. Займитесь не оптимизацией php-кода, а как правильно хранить данные ради грамотного масштабирования.

[3] Очень опытный программист не в состоянии придумать масштабируемую архитектуру сам. И никогда команда программистов не сделает масштабируемый стартап. Не потому, что люди глупые. Они - “не в теме”. Это их единственная проблема. Я испытал это на себе и только по этому утверждаю это. Глупость начинается тогда, когда программист думает, будто у него стартап переживет рост (антипаттерн - “фигня, нарежу таблички, все дела”). Это одно из великих заблуждений. Никакими средствами и ухищрениями вы этого не сможете сделать в разумные сроки. У меня имеются веские доказательства этого пункта - две “невозможных задачки” (чуть позже), которые не решаются традиционным подходом в программировании.

Команда программистов может создать масштабируемый проект самостоятельно года за два, если потратит их на архитектуру, а не программирование функционала. Последнее, сами понимаете, нереально и в жизни все занимаются только функционалом. И все советы, как надо делать масштабирование, воспринимают жестко и в штыки, мол, что за ахинею ты говоришь. Чуть ли не со слезами, сам видел.

Чтобы не тратить годы на велосипед - нужно воспользоваться готовыми платформами и решениями (не путайте это с неправильным вопросом “какой выбрать фрейморк”). Других путей нет.

[4] Немного печальной статистики о стартапщиках России. Я провожу в год несколько сотен собеседований с программистами и знаю, кто чем и в каких компаниях занимается. Около 50% программистов занимаются стартапами, клонами существующих соц.сетей или чем-то очень близким (антипаттерн - “я пишу соц.сеть, круче чем...”). У всех них замечательные идеи, как сделать лучше, только они являются страшной коммерческой тайной и потому подробностей не сообщается (тут можно смеяться). Я не обсуждаю очевидного, почему их творения не запустятся из-за самой идеи сделать клона, а только о чисто технических причинах. Занимались они своими проектами около 12-18 месяцев в среднем и все уволились. Ни один проект не запущен (либо не набрал и 10.000 пользователей).

Я задавал им 2-3 простых вопроса, относительно метода хранения “друзей” в их соц.сети, из которых делал вывод - их проект совершенно не масштабируемый. Ни один. Программисты об этом даже не думали. Все хранят в одной базе, в одной табличке и т.д. Это и есть ужас. Инвесторы годами платят деньги, программисты годами усердно/честно трудятся, а о самом главном не подумали - что их проект гарантированно никогда в жизни не запустится! Просто потому, что в нем нет масштабирования. Я конечно рад, что инвесторы и программисты заняты делом, просто есть совершенно банальные причины/доказательства - почему их проект заведомо мертв.

[5] Highload и архитектура крупного проекта - это особый вид решения задачи. Это вообще не программирование, в традиционном понимании. Например, забудьте, что вы эксперт по EXPLAIN. Он вам практически никогда не понадобится, т.к. в хайлоде применяются только примитивные запросы, типа SELECT по primary key. Много вещей, знанием и опытом которых вы гордитесь, как гуру программирования - не нужны! Голова - да, нужна.

Необходимо думать на этапе проектирования о важных вопросах. И не нужно - о несущественных вопросах: какой язык программирования выбрать, какую базу данных. Особо глупый вопрос - какой фреймворк выбрать, например, на PHP их десятки (доказательства - позже). Так же неважно, какую базу данных выбрать, т.к. мы будем использовать 1% ее возможностей, примитивные SELECT/UPDATE. Уважаемые авторы MySQL и PostgreSQL чуть ли не дерутся за графики мультитредовой производительности на всяких конференциях DevConf и Highload++, только забывают мелочь - в хайлоде это не интересно (т.е. не самое важное). Ну, нет у нас сложных запросов или критических нагрузок на один инстанс.

Первые шаги на правильном пути - осознать несущественность этих вопросов и спроектировать каждый из компонентов проекта горизонтально масштабируемым. Сложно объяснить, что именно делать. Зато легко показать, каким глупостям не нужно уделять внимание. Относительно выбора между MySQL и PostgreSQL: наша задача сделать так, чтобы ни на одном SQL инстансе, какой бы общей нагрузка ни была, не случился затык по производительности. Мы просто покупаем новый сервер и нагрузка сама перетекает туда. Вы достигли этого состояния? Тогда смело плюйте на графики производительности, вы - выше этого!

[6] “Разместим соц.сеть на облачном хостере” - стандартное забулуждение инвестора или программиста, желающего сэкономить на тратах за хостинг. Мелкое, но неприятное и опасное заблуждение, которое трудно аргументированно опровергнуть. Инвестору просто запудрили мозг дешевизной, а программист “не в теме”, но дает заключения (антипаттерн - “облако заменит масштабирование”). Минус - ужасающе медленные операции I/O, где-то раз в 10. Общая стоимость - не знаю, но думаю так же, минимум в 10 раз выше, по сравнению с арендой собственного железа. И нет масштабирования (в том смысле, которое нам нужно). И уж совершенно очевидно, что крупные соц.сети не живут на облаках.

О мифах относительно ВКонтакте после конференции Highload++ и круглого стола с разработчиками.

Недавно состоялась интересная конференция Highload++. Там выступали разработчики Vkontakte.ru и Facebook.com. Разумеется, за один-два часа выступления никто не передал великий секрет, как же оно устроено. Все высказали очень много интересных подробностей, но весьма поверхностно. Я попробую рассказать чуть больше, чем услышанные всеми общие слова. Мне это легко, т.к. занимаюсь тем же самым.

Прокомментирую некоторые высказывания посетителей известных ресурсов - Insight-it и Habrahabr. Большинство из них весьма типичные и от программистов, которые “не в теме”. Кстати, все ответы касаются и Facebook, никакой разницы нет.

Вопрос: Используется ли MySQL?

Ответ: Да. Это основное и главное хранилище данных. Не нужно относится к проекту, как к чему-то волшебному. Там тот же самый традиционный MySQL, с которым все мы работаем каждый день. Memcache применяется для хранения особо часто обновляемой информации, т.е. он хранит ~5% данных из основной SQL базы. За счет этого достигается скорость. Понимаю, вам не понятно, как засунуть 100 млн пользователей в MySQL (на мастер-классе расскажу). Но это так. Все одновременно и примитивно по идеи, и сложно в мелочах. В любом случае вас ждет взрыв мозга.

Точных цифр я конечно не знаю, но имеется пул MySQL серверов, где один из них хранит всю информацию о 500.000 - 1.000.000 пользователях. Таких серверов, исходя из общего числа пользователей - примерно 100-500 штук. Пользователи проявляют разную активность и серверы имеют разную мощность, поэтому споты пользователей (пачка ~1000 пользователей), могут спокойно мигрировать между серверами для достижения сбалансированной нагрузки. Возможность легкой миграции спотов - это и есть главное преимущество правильной честно горизонтально масштабируемой архитектуры проекта.

Вопрос: А там не говорилось, как они уникальные id создают?

Ответ: ID - это просто sequence (аналог поля auto_increment). Лежит он в какой-то no-sql базе, например memcache. Суть вопроса - те же опасения того, что соц.сеть очень сложно устроена. А все - элементарно, просто increment.

Вопрос: Как хранятся фото и видео на диске? Распределенные файловые системы?

Ответ: Все просто - как файл на диске обычного Linux сервера. Никаких изысков и особых распределенных сетевых файловых систем (забудьте об этом), все примитивно. При заливке фотки выбирается нужный спот и сервер (аналог шардинга профайла), php-скрипт на backend, принявший файл по upload, напрямую копирует файл на один из файловых стораджей. Естественно, используется избыточность: у данного сервера есть полный клон на другом сервере (не целиком, скорее всего - по спотам). Т.е. php-скрипт на самом деле копирует один файл сразу в 2-3 места. Но для выдачи, скорее всего, используется только один сервер (упрощает кеширование), зеркальные спорты понадобятся только, если первый сервер уничтожится физически.

Много непонятных мне споров про RAID. Совершенно не важно, используется RAID или нет. Важно то, наша система избыточного хранения данных выше всего этого. В этом смысл масштабирования - каким бы ни были скоростные характеристики дисков и их надежность, мы просто дублируем споты на разные физические устройства и заведомо обходим любые физические ограничения, которые были ранее или неожиданно возникнут в будущем.

Вопрос. Почему при удалении фотки она все равно доступна по прямому URL?

Ответ. Ох, сколько бреда пытаются додумать программисты, которые “не в теме”... Единственная причина: при удалении файла может возникнуть нарушение целостности, т.е. какая-то неизвестная страница соц.сети ссылается на этот файл, например в новостях или закладках. Если мы удалим файл, то возможно испортим какую-то свою страницу. Хранить данные о каждом файле, кто на него ссылается, и обрабатывать эти данные при удалении - очень накладно.

Поэтому файлы не удаляются только по той причине, что программистам жалко тратить уйму времени и мощностей (да и просто лень), чтобы написать удаление файлов с учетом целостности данных. Большинство объектов в соц.сети не удаляется, а просто помечается как удаленным. В списке вы этот объект больше не видите, но если кто-то ссылается на него - он выдается.

Когда я пробую этот вопрос разъяснить некоторым программистам, они с пеной у рта начинают возмущаться и доказывать: “Да что же сложного - просто удалить файл!”. Правильно, нет ничего сложного. Только нарушится целостность и наплодятся баги.

Еще кто-то ссылается на проблемы дефрагментации дисков... Возможно. Но лично мы ничего не удаляем, чтобы не заниматься лишней работой, которую можно отложить. Если делать корректное удаление файлов с диска или объектов в базе - это будет преждевременная оптимизация (а минусы этого процесса очень хорошо объясняются на каждой конференции разными известными докладчиками).

Цитата: “ВКонтакте использует PHP + XCache.”

Разъяснение. Разные версии PHP работают с XCache и APC по разному. Поэтому  просто будьте готовы, что со сменой PHP придется другой акселератор поставить, где багов и тормозов меньше. Ради highload не важно что ставить, только бы работало быстрее аналогов и не глючило.

Цитата: “Cервера многофункциональны и используются одновременно в нескольких ролях: Перебрасывание полуавтоматическое, Требуется перезапускать daemon'ы.”

Разъяснение. Не знаю, что хотел автор этой фразой сказать, но вот, что на самом деле происходит и о чем идет речь.

Представим, что у нас много серверов. Разобьем их на главные типы: пул MySQL, пул Backend PHP (+отдельные под Cron задачи), пул memcache, пул файловых стораджей, пул веб-балансеров (32 штуки) и т.д.

Рассмотрим особенности каждого из серверов. Memcache: занимает 70% памяти, где-то 10% CPU, 0% жесткого диска, 50% сетевого интерфейса (сеть должна быть свободной всегда для быстрого отклика). Файловый сторадж: файловый кеш 70% памяти, 0% CPU, 100% жесткого диска, скорость отклика по сети не очень важна.

Очевидна несправедливость: на сервере memcache почти полностью простаивает CPU и жесткий диск, а на файлом сторадже - CPU и сеть. Есть 2 типа сисадминов - правильные (большинство в мире) и не правильные (к ним относится ВКонтакте и я). Первый тип админов, не смотря на описанный выше очевидный простой ресурсов, стремятся разбить все сервера по типам исполняемых ими задач, потюнить ОС и т.д. Их цель - довести производительность главного назначения сервера до максимума. Второй тип админов стремится не дать простаивать ресурсам, объединяя некоторые не конфликтующие процессы на одном физическом сервере. Ну, жалко же, что на файловых стораджах куча памяти и cpu не используются! Туда столько всего полезного можно напихать, типа пассивных реплик любых других хранилищ для повышения общей производительности на отдачу контента.

Во ВКонтакте победила точка зрения второго типа, если я все правильно понял на том самом круглом столе Highload++.

Цитата: “Интерфейс доступа представляет собой расширенный протокол memcached... ключи возвращают результаты сложных запросов...”.

Разъяснение. Это не касается конечно волшебной базы. Смысл в том, что придуман универсальный интерфейс взаимодействия между PHP и  некоторой абстрактной базой данных или хранилища. PHP просто делает Memcache::get(“запрос”), соединяясь с неким сервером, а тот, поддерживая интерфейс memcache, обрабатывает запрос и выдает ответ.

В некоторых проектах так используется сверхбыстрый доступ к MySQL. Метод выбран из-за простоты и повсеместного внедрения модулей memcache во все языки.

Цитата: “Волшебная база на С”.

Разъяснение. Не понимаю, чего все прицепились к этому слову... В Контакте и Фейсбуке все хранится в MySQL. Все! Никакой волшебной базы не существует, как ее рисуют.

Существует специальное хранилище и  некая сишная софтина, которая создана только для скоростного анкетного поиска. Пожалуйста, не путайте понятия “как хранить и показать профайл” с “как найти среди 100 млн человек ID нужных профайлов по нужным полям”.

Все знают, что такое Sphinx. Волшебная база - это некий аналогичный программный продукт, хранилище данных, заточенное под анкетный поиск. Удивительно, какие фантазии раздуваются и слон из мухи растет просто на глазах...

Кто не помнит, примерно 1,5 года назад анкетный поиск ВКонтакте зверски тормозил - выдавал ответ через 20-30 секунд ожидания. Потом тормоза резко пропали. Результаты налицо. Жалко, что нет ни единого намека вообще ни на что об этом продукте: базовое хранилище - это реально ОЗУ компа (собственное хранилище) или все же SQL/memcache/redis? Я не успел об этом спросить.

В общем, я не знаю, но сомневаюсь, что даже для столь узкой задачи понадобилось свое хранилище данных сочинять. Скорее всего взято одно из этих трех хранилищ и оптимизирован код поиска. Далее элементарным шардингом (все данные не помешаются в ОЗУ одного сервера) и репликацией (нагрузку от поиска делим по слейвам в пуле) решаются все проблемы.

Вполне возможно, что сишная программа - это всего лишь новый вид команды к существующему memcache или redis. Я бы действовал так.

Цитата: “И что даёт эта статья? Только свой PR поднять?” (автор этой цитаты имеет ввиду статью на insight-it про Vkontakte, за что заработал “-41” голос на Хабре).

Комментатор на Хабре задал справедливый вопрос, который я обозначил в начале статьи. Общие слова о внешнем виде НЛО ни на миллиметр не приблизят вас к повторению системы. А человека, который это заметил - заминусовали. Моя цель - раскрыть все секреты и конкретные архитектуры. Откуда я это знаю? Занимаюсь тем же самым, только чуть в меньших объемах.

О недосказанном после Highload++.

А вот об интересных вопросах, которые реально важны, никто что-то и не спрашивал... Ну, кроме одного человека. Попробую добавить несколько реально серьезных тем, что удалось узнать.

О важности тюнинга memcache. (это один из ключевых вопросов моего мастер-класса)

Memcache хранит копию профайлов (некоторые переменные) в памяти, постоянно. В memcached добавили пару строк кода, чтобы ключи не удалялись со временем. В мемкеше хранится, допустим, 5% нужной информации. Все показы профайлов и записи изменений происходят через обращения к memcache, а в фоновом режиме они копируются в основную MySQL базу.

Помните, когда Контакт падал из-за проблем с электричеством, ушло 3 часа на восстановление? Хотя электроэнергии не было минут 5, наверно. Истинная причина состоит в том, что столь большое время нужно, чтобы правильно инициализировать сотни инстансов memcache копиями профайлов из MySQL. Те должны включится, починить свои диски и таблицы после падения, прочитать и отдать всю информацию по SQL запросам скриптов инициализации в memcache. Таким образом часть пользователей получает доступ к своему профайлу быстрее, часть - медленнее.

Сколько же глупостей люди написали, пытаясь объяснить эти три часа и сопоставить с тем, что дизеля то включились через пару минут... Наш проект где-то раз в 20 меньше ВКонтакте и подобное восстановление занимает около минут 15 - перезагрузка серверов, старт ОС, загрузка десятков инстансов MySQL с длительной проверкой всех таблиц, копирование в данных в no-sql хранилище, открытие доступа к проекту после визуального осмотра.

Метод подписки / функционирование новостей.

Одна из самых сложных и увлекательных функций соц.сети - это подписка (лента / новости). К сожалению, об этом никто не спрашивал.

Я знаю о 2-х кардинально разных методах подписки:
1) репликация после генерирования события на споты (инициатор - автор события) с той целью, чтобы к моменту прихода веб-пользователя все уже было накоплено и мгновенно в 1 SQL запрос отдано;
2) централизованное аккумулирование всех событий в быстрой памяти, сбор по команде веб-пользователя (инициатор - веб-пользователь, тот, кто смотрит).

На конференции же Павел Дуров заявил, что они, как и Facebook, применяют второй тип сбора новостей. Второй метод имеет существенные баги, например, не все новости всегда доступны (иногда наблюдаю). Зато первый потребляет в разы больше места на жестких дисках. Идеального ничего нет...

Да, я тут в сети видел статью в инете, как сделать ленту обновлений на MongoDB и PHP, разумеется, это не будет работать уже при 1 млн пользователей в базе, т.к. решение не масштабируемо. Но для небольшого сайта приемлемо.

Весь пул MySQL в единственном датацентре.

Архитектура ВКонтакте еще не позволяет размножится до нескольких дата-центров. Мало кто понимает, но это очень важный показатель крупнейших проектов.  Я предполагаю, что Facebook эту стадию давно прошел (точно не проверял). А у ВКонтакте этот сложный шаг еще впереди.

Правда, если они останутся в рамках СНГ, то надобности в этом не будет. Связали два дата-центра через улицу толстым каналом и решение по прежнему SQL-неделимое, но все же в 2х зданиях.

В этом пункте я имею ввиду только SQL. Файлы и прочая информация роли не играет, переносится куда угодно элементарно.

Заключение.

В Петербурге, Киеве, Москве и Новосибирске вскоре я проведу мастер-классы, где за 8 часов постараюсь обучить слушателей азам построения крупных масштабируемых проектов: http://php.spb.ru - запись уже открыта [эта статья написана в 2010г]

Так же мне было бы интересно узнать, какими узкоспециализированным вопросами по процессу разработки архитектуры интересуются читатели.

До встречи на мастер-классе :)

В следующей статье я отвечу на все поступившие комментарии:
продолжение в посте #2 => http://spb-borodin.livejournal.com/779.html

---------------------

http://php.spb.ru - Запись на мастер-класс по #Highload на 2013 год
Next post
Up