Cassandra годами остаётся рабочей лошадкой для больших объёмов записей, но её JVM-профиль — отдельная профессия: heap, сборка мусора, паузы, тюнинг. ScyllaDB переписывает ту же модель данных на C++ и меняет архитектуру: каждый поток владеет своим ядром, данными и кэшем, а сборщик мусора отсутствует как класс. При этом язык запросов остаётся CQL, и драйверы Cassandra обычно подходят без изменений. Разберём, как это работает и что нужно проверить перед миграцией.
Архитектура: почему быстрее
Cassandra распределяет данные по узлам и внутри узла использует общий пул потоков. ScyllaDB идёт дальше: узел делится на шарды, по числу ядер, и каждый шард обслуживает свой участок данных одним потоком. Нет блокировок на общих структурах, нет переключений контекста на горячем пути, нет JVM и её пауз.
Отсюда практические следствия. Память делится между шардами, и её нужно планировать заранее. Число ядер важнее тактовой частоты. А параметры вроде --smp и --memory при запуске в контейнере становятся частью конфигурации, а не мелочью.
Когда подходит
ScyllaDB выбирают для сценариев с интенсивной записью и предсказуемым доступом по ключу: события, метрики, каталоги, ленты, счётчики, телеметрия. Модель wide-column хорошо ложится на данные, где запрос всегда начинается с partition key. Ключ выбирают так, чтобы запись равномерно ложилась по узлам, а размер партиции оставался в разумных пределах: на гигантских партициях чтение заметно проседает.
Не стоит ждать от неё того, чего нет: JOIN, многострочных транзакций и произвольных агрегатов по всей таблице. Лёгкие транзакции (LWT) поддерживаются, но стоят дороже, чем в некоторых СУБД. Если нужны отчёты по свободным фильтрам, рядом обычно ставят аналитическое хранилище.
Быстрый стенд в Docker
Для знакомства достаточно одного контейнера с ограничением ресурсов. Такой запуск не для продакшена, но модель данных и CQL проверить позволяет.
docker run --name scylla -d \
-p 9042:9042 \
-v scylla-data:/var/lib/scylla \
scylladb/scylla --smp 2 --memory 2G --overprovisioned 1
docker logs -f scylla
docker exec -it scylla nodetool status
docker exec -it scylla cqlsh
Флаг --overprovisioned 1 говорит планировщику, что машина не выделена целиком, и убирает агрессивные настройки. На реальном сервере его не ставят: там ScyllaDB должна получить все ядра и память.
Установка на сервер
Для продакшена используют пакеты из официального репозитория или образ с правильным пробросом дисков. После установки запускают scylla_setup: мастер проверит RAID, NTP, лимиты файловых дескрипторов, отключит лишние службы и настроит fstrim для SSD.
sudo scylla_setup
sudo systemctl status scylla-server
sudo journalctl -u scylla-server -n 100 --no-pager
sudo ss -ltnp | grep -E ':(9042|7000|7001|9180)'
Порты 7000 и 7001 — межкластерное общение, 9042 — CQL, 9180 — метрики Prometheus. Наружу открывают только 9042 и то лишь при необходимости: клиенты должны ходить по приватной сети.
Конфигурация узла
Основные параметры лежат в /etc/scylla/scylla.yaml. Для первого узла список seeds указывает на него самого; остальные узлы получают адрес первого. Адреса должны быть стабильными, иначе кластер потеряет узел после перезагрузки.
cluster_name: 'prod-cluster'
num_tokens: 256
seeds: "10.0.0.11"
listen_address: 10.0.0.11
rpc_address: 10.0.0.11
endpoint_snitch: GossipingPropertyFileSnitch
Для нескольких дата-центров snitch настраивают отдельно, иначе реплики окажутся в неожиданных местах. После правки конфигурации узел перезапускают по одному и смотрят nodetool status: все узлы должны быть в состоянии UN.
Модель данных и CQL
Ключ партиции определяет, на каком узле и шарде лежат данные. Ключ кластеризации задаёт порядок внутри партиции. Ошибка в выборе ключа приводит к горячим партициям, и никакое железо этого не компенсирует.
CREATE KEYSPACE events WITH replication = {
'class': 'NetworkTopologyStrategy',
'datacenter1': 3
};
CREATE TABLE events.page_view (
user_id uuid,
bucket date,
event_time timestamp,
url text,
PRIMARY KEY ((user_id, bucket), event_time)
) WITH CLUSTERING ORDER BY (event_time DESC)
AND default_time_to_live = 7776000;
TTL в три месяца здесь не декоративный: старые события помечаются tombstones и удаляются при компакции, а без срока жизни таблица растёт бесконечно. Для метрик и логов TTL обязателен.
Запросы и драйверы
Работают официальные драйверы Cassandra для Java, Python, Go и Node.js. Главное правило — prepared statements: они кэшируют разбор запроса и снижают нагрузку на координатор.
cqlsh 10.0.0.11 9042 -u cassandra -p 'пароль'
CONSISTENCY LOCAL_QUORUM;
SELECT url FROM events.page_view
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000
AND bucket = '2026-02-01'
LIMIT 50;
Уровень согласованности выбирают под задачу: ONE быстрее, QUORUM надёжнее при отказе узла. Для записи событий часто достаточно LOCAL_ONE, для финансовых операций — кворум.
Компакция и хранение
По умолчанию используется Size-Tiered Compaction Strategy. Для временных рядов лучше подходит Time-Window, которая группирует данные по окнам времени и упрощает удаление старых SSTable. В новых выпусках появились tablets — альтернатива vnodes, упрощающая ребалансировку.
Менять стратегию на живой таблице можно, но делать это стоит в окно низкой нагрузки и с пониманием объёма перезаписи. Компакция создаёт дополнительный ввод-вывод, и на перегруженном диске это заметно.
Диагностика
Первое, что смотрят при проблемах, — состояние кластера и гистограммы задержек. nodetool status показывает узлы и объём данных, nodetool tablestats — размеры и число SSTable, proxyhistograms — распределение времени координатора.
nodetool status
nodetool tablestats events.page_view
nodetool proxyhistograms
curl -s localhost:9180/metrics | grep scylla_transport_requests
Метрики на 9180 отдают сотни счётчиков. Начните с задержек транспорта, числа таймаутов и заполнения диска. Если p99 растёт, а диск и CPU свободны, ищите горячую партицию и неоптимальный запрос.
- рост p99 без нагрузки на CPU и диск — горячая партиция;
- таймауты и очередь на запись — нехватка памяти или медленный диск;
- частая компакция — слишком много мелких SSTable.
Миграция с Cassandra
Совместимость не абсолютная. CQL и драйверы переносятся, но кастомные JMX-метрики, часть UDF и внутренние настройки — нет. Проверьте схему, типы и уровни согласованности на тестовом кластере.
Данные переносят через sstableloader или специализированный мигратор. Для больших объёмов используют потоковую перекачку с двойной записью на переходном этапе: сначала читают из старого кластера, потом переключают трафик.
Итог
ScyllaDB даёт предсказуемую задержку и высокую плотность записи там, где Cassandra требует тюнинга JVM. Начните с одного узла в Docker, проверьте модель данных на реальных запросах, затем разверните три узла с репликацией и мониторингом. И не забывайте про TTL, бэкапы и тест восстановления — скорость не отменяет этих обязанностей.