Как Discord перенес триллионы сообщений в ScyllaDB
В начале 2022 года Discord хранил триллионы сообщений на 177 узлах Cassandra. Cassandra отлично подходила для высокой нагрузки на запись. Проблема была в чтении: популярный канал мог отправлять тысячи запросов на чтение сообщений. Все они шли к одному разделу, перегружали его и тормозили запросы других каналов на тех же серверах. К тому же уплотнение данных (compaction) постоянно отставало, а паузы сборщика мусора JVM приводили к скачкам задержек.
Чтобы решить проблемы на уровне базы данных, Discord заменил Cassandra на ScyllaDB - совместимую реализацию на C++. Она избавила систему от пауз сборщика мусора JVM, сделала хранилище быстрее и проще в обслуживании.
Но более быстрая база данных не защищает от ситуации, когда тысячи людей одновременно запрашивают одно и то же сообщение. Для этого Discord поставил перед базой данных сервисы данных на Rust. Запросы одного канала направляются на один экземпляр сервиса, где параллельные чтения одного сообщения объединяются в один запрос к базе данных.
Новый кластер работает на 72 узлах вместо 177, а p99 времени чтения упал со 125 мс до стабильных 15 мс.
Проблема
Discord хранил сообщения в Cassandra с 2017 года. К началу 2022 года кластер вырос до 177 узлов с триллионами сообщений. Все они хранились в одной таблице:
В Cassandra составной ключ (channel_id, bucket) служит ключом партиционирования и определяет, на каких серверах лежат данные. Канал - это чат на сервере Discord, а bucket - окно времени. Вместе они собирают сообщения канала за определенный период в один раздел, который реплицируется на [... читать дальше]
В начале 2022 года Discord хранил триллионы сообщений на 177 узлах Cassandra. Cassandra отлично подходила для высокой нагрузки на запись. Проблема была в чтении: популярный канал мог отправлять тысячи запросов на чтение сообщений. Все они шли к одному разделу, перегружали его и тормозили запросы других каналов на тех же серверах. К тому же уплотнение данных (compaction) постоянно отставало, а паузы сборщика мусора JVM приводили к скачкам задержек.
Чтобы решить проблемы на уровне базы данных, Discord заменил Cassandra на ScyllaDB - совместимую реализацию на C++. Она избавила систему от пауз сборщика мусора JVM, сделала хранилище быстрее и проще в обслуживании.
Но более быстрая база данных не защищает от ситуации, когда тысячи людей одновременно запрашивают одно и то же сообщение. Для этого Discord поставил перед базой данных сервисы данных на Rust. Запросы одного канала направляются на один экземпляр сервиса, где параллельные чтения одного сообщения объединяются в один запрос к базе данных.
Новый кластер работает на 72 узлах вместо 177, а p99 времени чтения упал со 125 мс до стабильных 15 мс.
Проблема
Discord хранил сообщения в Cassandra с 2017 года. К началу 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);
В Cassandra составной ключ (channel_id, bucket) служит ключом партиционирования и определяет, на каких серверах лежат данные. Канал - это чат на сервере Discord, а bucket - окно времени. Вместе они собирают сообщения канала за определенный период в один раздел, который реплицируется на [... читать дальше]