В 2017 году команда Discord рассказала, как они начали использовать MongoDB, но перенесли свои данные в Cassandra, поскольку искали масштабируемую, отказоустойчивую и относительно не требующую обслуживания базу данных.

Спустя несколько лет в кластере Discord Cassandra возникли серьезные проблемы с производительностью, которые требовали все больших усилий для простого обслуживания, а не улучшения.

Что мы здесь рассмотрим…

  1. Проблемы Кассандры в Discord
  2. Изменение архитектуры — ScyllaDB
  3. Как команда Discord справилась с вышеуказанными проблемами?
  4. ‍Очень большая миграция — переход на ScyllaDB
  5. Заключение

Проблемы Кассандры в Discord

  • В 2017 году команда Discord запустила 12 узлов Cassandra, на которых хранились миллиарды сообщений.
  • На начало 2022 года у него было 177 узлов с триллионами сообщений. К их огорчению, это была очень тяжелая система —

а. их дежурную команду часто вызывали по пейджерам по поводу проблем с базой данных, задержка была непредсказуемой, и

б. Непредсказуемая задержка

в. им приходилось сокращать операции по техническому обслуживанию, выполнение которых становилось слишком дорогим.

  • Что вызвало эти проблемы? Сначала давайте посмотрим на сообщение.
CREATE TABLE messages ( channel_id bigint, bucket int, 
message_id bigint, author_id bigint, content text, PRIMARY KEY 
((channel_id, bucket), message_id)) WITH CLUSTERING ORDER BY 
(message_id DESC);
  • Приведенный выше оператор CQL представляет собой минимальную версию их схемы сообщений. Каждый идентификатор, который они используют, представляет собой снежинку, что позволяет сортировать его в хронологическом порядке. Они разделяют свои сообщения по каналу, по которому они отправляются, а также по сегменту, который представляет собой статическое временное окно.
  • В этом разделении кроется потенциальная проблема с производительностью: сервер с небольшой группой друзей имеет тенденцию отправлять на порядки меньше сообщений, чем сервер с сотнями тысяч людей.
  • В Cassandra чтение обходится дороже, чем запись. Множество одновременных операций чтения при взаимодействии пользователей с серверами могут обнаружить раздел, который они образно называют «горячим разделом». Размер их набора данных в сочетании с этими шаблонами доступа привел к проблемам за их кластер.
  • Когда они сталкивались с горячим разделом, это часто влияло на задержку во всем кластере базы данных. Одна пара каналов и сегментов получила большой объем трафика, и задержка в узле будет увеличиваться по мере того, как узел будет все сильнее и сильнее пытаться обслуживать трафик и все больше и больше отставать.
  • Задачи обслуживания кластера также часто вызывали проблемы. Они были склонны отставать в сжатии, когда Кассандра сжимала SSTables на диске для более производительного чтения. Мало того, что их чтение тогда было более дорогим, но они также наблюдали каскадную задержку, когда узел пытался сжать.

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

Изменение архитектуры

  • Их кластер сообщений был не единственной базой данных Cassandra. У них было еще несколько кластеров, и каждый из них имел схожие (хотя, возможно, и не столь серьезные) недостатки.
  • ScyllaDB — совместимая с Cassandra база данных, написанная на C++. Обещания лучшей производительности, более быстрого ремонта, более сильной изоляции рабочих нагрузок благодаря архитектуре с сегментами на ядро ​​и жизни без сборки мусора звучали весьма привлекательно.

  • Поэкспериментировав со ScyllaDB и наблюдая улучшения в тестировании, они приняли решение перенести все свои базы данных.‍

Как команда Discord справилась с вышеуказанными проблемами?

  • С Кассандрой боролись с горячими перегородками. Высокий трафик к данному разделу привел к неограниченному параллелизму, что привело к каскадной задержке, при которой задержка последующих запросов продолжала расти. Если бы они могли контролировать объем одновременного трафика к «горячим» разделам, они могли бы защитить базу данных от перегрузки.
  • Для выполнения этой задачи они написали так называемые службы данных — промежуточные службы, которые находятся между их монолитом API и кластерами баз данных. При написании своих сервисов данных они выбрали язык, который все чаще и чаще используют в Discord: Rust! Это дало им высокую скорость работы с C/C++ без необходимости жертвовать безопасностью.
  • Экосистема Токио Rust — это огромная основа для построения системы с асинхронным вводом-выводом, а язык имеет поддержку драйверов как для Cassandra, так и для ScyllaDB.
  • Их службы данных располагаются между API и кластерами ScyllaDB. Они содержат примерно одну конечную точку gRPC на каждый запрос к базе данных и намеренно не содержат бизнес-логики. Важной особенностью их служб передачи данных является объединение запросов. Если несколько пользователей одновременно запрашивают одну и ту же строку, они будут запрашивать базу данных только один раз.
  • Первый пользователь, который делает запрос, запускает рабочую задачу в службе. Последующие запросы проверят наличие этой задачи и подпишутся на нее. Эта рабочая задача запросит базу данных и вернет строку всем подписчикам.
  • В этом сила Rust в действии: он упростил написание безопасного параллельного кода.

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

‍Очень большая миграция — переход на ScyllaDB

  1. Подготовьте новый кластер ScyllaDB, используя топологию хранилища «супердиск».

2. Выполните двойную запись новых данных в Cassandra и ScyllaDB, одновременно настраивая Spark migrator ScyllaDB, инструмент для миграции данных.

3. Они расширили свою библиотеку сервисов данных для выполнения крупномасштабной миграции данных с использованием языка программирования Rust, что сократило расчетное время с 3 месяцев до 9 дней.

4. Миграция столкнулась с проблемой, когда она застряла на уровне 99,9999 % из-за больших диапазонов захоронений в последних нескольких диапазонах токенов данных. Команда решила эту проблему, сжимая диапазон токенов, и миграция была успешно завершена.

5. Автоматическая проверка данных выполнялась путем сравнения небольшого процента операций чтения из обеих баз данных, что обеспечивало точный перенос данных. Кластер ScyllaDB хорошо работал при полном рабочем трафике, в то время как у Cassandra часто возникали проблемы с задержкой.

Несколько месяцев спустя… Заключение

  • Они переходят от 177 узлов Cassandra к всего лишь 72 узлам ScyllaDB. Каждый узел ScyllaDB имеет 9 ТБ дискового пространства по сравнению со средним показателем в 4 ТБ на узел Cassandra.

  • их латентность хвоста также значительно улучшилась. Например, загрузка исторических сообщений имела p99 в пределах 40–125 мс на Cassandra, при этом ScyllaDB имела приятную задержку p99 в 15 мс, а производительность вставки сообщений увеличивалась с 5–70 мс p99 на Cassandra до стабильных 5 мс p99 на ScyllaDB.

Не забудьте нажать кнопки «Хлопнуть» и «Подписаться», чтобы помочь мне писать больше подобных статей.

Рекомендации

Вы также можете прочитать —