Промышленные системы или почему глючит Facebook

Вступление

На прошлой неделе завершилась очередная итерация эпического рабочего проекта, я немного отдохнул, и теперь наконец-то могу написать эту статью.

Говорить будем о том, почему системы масштаба Facebook или Сбербанка иногда конкретно глючат либо просто ломаются к чертям. Казалось бы, если ты контора, у которой полтора миллиарда пользователей (Facebook), то будь добр обеспечить нормальное тестирование, чтобы все работало без перерывов и можно было удалить сто друзей подряд, не сталкиваясь с глюками. Я часто слышу подобные жалобы, так что решил написать немного про то, как вообще устроены ИТ-системы, рассчитанные на работу с впечатляющим количеством пользователей и данных.

Сразу оговорюсь: я не работаю ни в Фейсбуке, ни в Сбере. Я вообще не программист, а риск-менеджер, которому волею судеб приходится довольно много работать с базами данных, и мне просто нравится изучать работу компьютерных систем. Так что за достоверность написанного не отвечаю, только за общий посыл.

Резюме

Есть ИТ-система, которая должна работать 24/7 с кучей пользователей, которые постоянно в нее что-то пишут. Есть две основные проблемы, вызывающие глюки:

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

Вот, в общем-то, и все. Ниже – подробнее о каждом из пунктов.

Синхронное и асинхронное выполнение запросов

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

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

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

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

Вы меня простите, очень люблю образный язык, но логика работы компьютерных систем такая же. У Facebook очень, очень много пользователей, асинхронное выполнение операций выглядит для нас быстрее, а ждать никто не любит. Попробуйте сделать пятисекундную загрузку главной страницы на любом сайте и посмотрите, что останется от аудитории. Ничего не останется.

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

В системах такого размера нельзя все хранить на одной машине. Программная часть работает отдельно, тяжелые данные вроде картинок должны лежать отдельно.

Когда столько пользователей, работа с любыми операциями записи должна делаться очень аккуратно. У Facebook нас полтора миллиарда, и пользователей обслуживает огромная сеть серверов. Представим себе, что все запросы выполнялись бы синхронно. В течение дня, часа, минуты количество запросов сильно и непредсказуемо колеблется – пришлось бы держать огромные запасные мощности, чтобы все это не тормозило на пиковых нагрузках. А очередь можно разбирать в заданном темпе.

Для пользователя это удобно, потому что быстро: затратные задачи идут в фоне, а мы смотрим котиков. А неудобно из-за возможных глюков. Для меня неудивительно, что если убить 500 запросов на добавление в друзья подряд, а потом быренько обновить страницу, то можно увидеть якобы удаленные запросы, но сделать с ними ничего нельзя (видел скриншоты у Алекса Экслера пару недель назад). Потому что они в компьютерном чистилище – очереди на небытие. И пока у системы не дойдут руки до их фактического удаления, можно видеть Странное и Невероятное (а также их подругу Какую-то Фигню). Но почему бы не сделать обработку подобных ситуаций, чтобы пользователь не видел глюков, спросите вы. У Facebook же армия разработчиков, чего им стоит... И тут мы подходим ко второму пункту.

Промышленные системы

Facebook очень большой. Просто неепически огромный. У них сейчас в месяц активны полтора миллиарда пользователей. Для сравнения на этот сайт в его разных ипостасях (matamune.ru, страница в Facebook) в месяц заходит пара тысяч человек. На гиганта среди персональных проектов – exler.ru – порядка миллиона.

Проведем небольшой мысленный эксперимент. Вот вы набрали адрес www.facebook.com в адресной строке, служба доменных имен интернета преобразовала это имя в IP-адрес и ваш компьютер достучался до машины, которая по нему обнаружилась. В случае сравнительно небольшого проекта вроде моего, вы бы сразу начали общаться с сервером сайта. Но у Facebook столько запросов в секунду, что этого никакая машина не выдержит, поэтому должна быть специальная подсистема распределения запросов – устройств, которые только тем и занимаются, что раскидывают пользователей по идентичным серверам, показывающим пользователям страничку Facebook.

Разумеется, на этих серверах ничего толком не хранится, кроме копии дизайна сайта. Профили, сообщения, фотографии, сохраненные ссылки и прочее, и прочее всех пользователей Facebook – это немыслимое количество информации. Значит сервер, который готовит вашу страничку, должен запросить все необходимые данные из специальных хранилищ, в которых все это лежит. Он направляет запрос, тот попадает в другую специальную подсистему, находящую, на каких машинах есть копии того, что вам надо. Адреса данных передаются серверу, готовящему страничку, и тот теперь может ее собрать. Это упрощенная схема: представители Facebook утверждают, что домашняя страничка пользователя собирается на основе данных, лежащих на нескольких сотнях машин, и делается это меньше, чем за секунду.

Добавим к этому всему необходимость резервных копий всего и вся. Вы же не хотите, чтобы группа обсуждения роли котиков в фильмах Тарантино стала недоступной, потому что где-то там затопило подстанцию и перестали работать сервера?

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

Объясним на примере банковского сервиса небольшого банка. Система обслуживает отделения. Следите за руками. Первая копия – основная. С ней работают рядовые сотрудники, включая операционистов. Вторая копия – резервная. Там периодически сохраняется резервная копия данных, которая восстанавливается, если с основной что-то случилось. Третья копия – тестовая среда, на которой программисты тестируют свои разработки. Эта копия загромождена кучей программ, нужных только в процессе разработки. Четвертая – это чистая копия основной среды, на которой осуществляется окончательное тестирование

Так вот, чтобы нормально оттестировать нужный функционал, нужно его установить на четвертую систему – полностью идентичную основной копию, после чего проверить его под нагрузками, идентичными настоящим. Я только что рассказал, какой монстр чему-либо размера Facebook, просто чтобы там все работало. В действительности, наверняка, все гораздо сложнее, чем может со стороны предположить относительный любитель вроде меня. Полностью повторить этот кошмар для простого тестирования – неприемлемо дорого. Создать полноценную симуляцию полутора миллиарда пользователей – того хуже. Вот и тестируют бедняги новые фишки движка на относительно малой системе на тестовых нагрузках, сформированных на основе статистических данных. Уверен, что там не дураки, и они стараются все корректно масштабировать, но когда по определению неполноценно оттестированный продукт запускают в эксплуатацию, ошибки производительности и странное поведение почти неизбежны. Добавим к этом тот факт, что апдейты разного размера Facebook, по их же словам, выпускает ежедневно.

Вывод

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

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

Также в разделе:

Как работает логин через соцсети
Краткое руководство по резервному копированию данных
Быстрая настройка мета-тегов для Facebook

Опубликовано: 23.11.2015

Комментарии (1)


(c) Александр Кирко, 2016