Как масштабировать архитектуру чата с высокой нагрузкой: опыт Facebook | OTUS

Как масштабировать архитектуру чата с высокой нагрузкой: опыт Facebook

HL_Deep_28.11-5020-1f2565.png

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

1. Введение

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

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

2. Об использовании сторонних решений

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

3. Стек технологий и архитектура

Facebook_messenger_chat_backend_1-20219-e0a981.jpg

Вся система включает в себя несколько модулей, которые свободно связаны между собой модулей и работают друг с другом. Это: — веб-узел; — пользовательский интерфейс; — кластер каналов; — модуль определения присутствия пользователей; — журналирование чата.

3.1 Пользовательский интерфейс

Интерфейс написан на JavaScript, а для серверного рендеринга используется PHP. Длительные сессии подключения между сервером и клиентом настроены посредством AJAX. А вот от Flash отказались. Во-первых, применение Flash требует у пользователей установку соответствующего плагина, что снижает удобство. Кроме того, Flash небезопасен.

Что касается потока сообщений, то это смесь технологий pull и push. Поначалу клиент отправляет pull-запрос на получение имеющихся сообщений и одновременно подписывается на дельта-обновления, которые, в свою очередь, основаны на push-технологии. Если пользователь подписался на обновления, Facebook начинает отправлять их ему по мере появления.

3.2 Бэкенд

Здесь применяется PHP, а обработка web-запросов происходит в чистом виде. Бэкенд отвечает за аутентификацию пользователей, историю чата, настройки приватности, обновления, получаемые от друзей, и за прочую функциональность.

3.3 Модуль, определяющий пользовательское присутствие

Модуль обеспечивает предоставление информации о доступности соединений и/или друзей в режиме онлайн. Он написан на C++ и считается самой нагруженной частью системы (в основном, из-за запросов типа «вопрос-ответ»). Кроме того, модуль собирает информацию об online-пользователях, отправляя данные клиенту по запросу.

3.4 Кластер каналов

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

В серверах кластера каналов применяется библиотека Mochi Web. Эта библиотека служит для построения «лёгких» HTTP-серверов. Сообщения юзеров выстраиваются в очередь на серверах кластера, причём каждое сообщение получает своё порядковый номер, необходимый для создания синхронной связи между любыми 2-мя и более пользователями.

3.5 Журналирование чата

Регистрация метаданных чата и прочей информации выполняется посредством журналирования сообщений. Функционал написан на C++ и обеспечивает запись данных между загрузками UI страниц.

4. Развёртывание сервиса и масштабируемость

Определение пользовательского присутствия и журналирование чата реплицированы во всех ЦОД Facebook, при этом данные серверов каналов хранятся лишь в одном специализированном ЦОД, что необходимо для получения высокой согласованности.

Модули бэкенда связаны слабо, общаясь между собой через протокол связи Thrift. Он облегчает коммуникацию между службами, которые работают на разнородных технологиях. Речь идёт о разработанном в Facebook фреймворке для сериализации и вызова удалённых процедур — RPC (Remote Procedure Call). RPC обеспечивает общение между сервисами, помогая организовать слаженную работу систем, которые написаны на Erlang, PHP, C++ и JavaScript.

4.1 Наиболее ресурсоёмкая операция

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

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

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

Чтобы управлять таким большим числом пользовательских подключений, пришлось увеличить количество балансировщиков нагрузки, в результате чего способность инфраструктуры управлять одновременными пользовательскими соединениями существенно возросла. Таким образом удалось решить проблему и устранить «слабое место», которое ранее вызывало перебои в работе онлайн-чатов при пиковых нагрузках.

5. Синхронизация хранилищ данных и сообщений

Как уже было упомянуто, для управления синхронной связью используется операция присвоения сообщениям порядковых номеров. Также в Facebook создали протокол синхронизации Messenger Sync Protocol, на 40 % сокративший использование немедийных данных. Вследствие этого, уменьшилась и перегруженность сети.

Кроме того, инженеры Facebook разработали сервис Iris, обеспечивающий обновление сообщений в упорядоченной очереди. Эта очередь имеет различные указатели, помогающие отслеживать обновления сообщений, включая сообщения, которые уже были прочитаны, или сообщения, которые ещё не открывались. Если старые беседы извлекаются из стандартного хранилища данных, то последние сообщения отправляются пользователям из памяти Iris.

Facebook_messenger_chat_min_jpeg_633x1024_1-20219-2b9aa0.jpg

Iris спроектирован на основе Flash-памяти и MySQL. Сначала в качестве хранилища мессенджера применялась Hbase, однако позже Hbase была мигрирована в MyRocks — открытый проект БД, написанный в Facebook, где в качестве движка MySQL для хранения данных используется RocksDB.

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться
Популярное
Сегодня тут пусто