Cassandra — широкостолбцовая распределённая база данных, которая держит запись и чтение при росте узлов почти линейно. Она не имеет единой точки отказа, переживает выпадение стоек и хорошо подходит для временных рядов, сообщений, телеметрии и каталогов с известными запросами. Но это не «PostgreSQL, только быстрее»: модель данных здесь строится от запроса, а не от нормализованной схемы. Разберём архитектуру, CQL и эксплуатацию без иллюзий.

Когда Cassandra оправдана

База выигрывает там, где много записи, данные растут горизонтально, а геораспределённость важнее строгих транзакций. Она плохо подходит для ad-hoc аналитики, сложных join-ов, отчётов по всей таблице и операций, которым нужна немедленная согласованность всех реплик.

  • Подходит: события, метрики, журналы, чаты, IoT, корзины с простыми ключами.
  • Не подходит: OLAP, финансовая отчётность, произвольные фильтры, малые данные без роста.
  • Ключевой принцип: сначала запрос, потом таблица.

Кольцо, репликация и согласованность

Данные распределяются по кольцу с помощью consistent hashing, а virtual nodes сглаживают неравномерность. Фактор репликации RF задаёт число копий, стратегия NetworkTopologyStrategy размещает их по стойкам и дата-центрам. Координатор принимает запрос, находит реплики и собирает ответ.

Уровни согласованности ONE, QUORUM и ALL определяют, сколько подтверждений ждать. Для устойчивости к потере одной реплики при RF=3 используйте QUORUM для записи и чтения: сумма кворумов больше RF даёт пересечение наборов. Но это не транзакции: конфликтующие записи разрешаются по времени, а «последняя» запись может победить не так, как вы ожидали.

Запись сначала попадает в commit log и memtable, затем сбрасывается в SSTable. Если реплика недоступна, координатор может сохранить hinted handoff и доставить данные позже; это не отменяет repair, а лишь сокращает окно расхождения. Читать с QUORUM при свежей записи дороже, но предсказуемее. Для критических операций выбирайте уровень согласованности осознанно и проверяйте задержки на реальном профиле нагрузки.

Лаборатория в Docker

Для знакомства достаточно одного узла, но поведение кластера лучше смотреть на трёх. В лаборатории не используйте боевые данные и не открывайте порт 9042 в интернет.

docker run -d --name cass1 -p 9042:9042 cassandra:latest
docker exec -it cass1 nodetool status
docker exec -it cass1 cqlsh
docker logs --tail 50 cass1

Официальный образ стартует долго: сначала JVM, затем gossip и инициализация схемы. Если cqlsh не подключается, дождитесь статуса UN у узла, а не перезапускайте контейнер каждые полминуты.

Моделирование данных

Partition key определяет узел и должен быть равномерным. Clustering columns задают порядок внутри раздела и позволяют читать диапазоны. Слишком большой раздел — это горячая точка и долгие compaction; миллионы строк на раздел обычно — признак ошибки.

Денормализация здесь ожидаема: одна таблица под один запрос. Дублирование данных дешевле join-ов, которых Cassandra не умеет. Materialized views и вторичные индексы существуют, но имеют ограничения и не заменяют продуманную схему.

CQL на практике

CREATE KEYSPACE telemetry
WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': 3};

CREATE TABLE telemetry.events (
  device_id uuid,
  bucket date,
  event_time timestamp,
  metric text,
  value double,
  PRIMARY KEY ((device_id, bucket), event_time, metric)
) WITH CLUSTERING ORDER BY (event_time DESC, metric ASC)
  AND default_time_to_live = 7776000;

Составной partition key из устройства и суток ограничивает размер раздела. TTL автоматически удаляет старые данные, но не освобождает место мгновенно: сначала появляются tombstones, затем их убирает compaction.

INSERT INTO telemetry.events (device_id, bucket, event_time, metric, value)
VALUES (550e8400-e29b-41d4-a716-446655440000, '2026-11-06',
        toTimestamp(now()), 'temperature', 21.5)
USING TTL 86400;

SELECT event_time, metric, value
FROM telemetry.events
WHERE device_id = 550e8400-e29b-41d4-a716-446655440000
  AND bucket = '2026-11-06'
LIMIT 100;

Запрос без partition key приведёт к полному сканированию и предупреждению. Это не «медленно», а потенциально смертельно для кластера. Для глобальных выборок используйте отдельные таблицы-индексы или внешнюю аналитику.

Compaction, tombstones и repair

Запись в Cassandra неизменяема: обновление создаёт новую версию, удаление — tombstone. Compaction сливает SSTable и выбрасывает устаревшие данные. Стратегия зависит от нагрузки: STCS хороша для записи, LCS — для чтения, TWCS — для временных рядов с одинаковым TTL.

nodetool compactionstats
nodetool tablestats telemetry events
nodetool repair -pr telemetry
nodetool cleanup

Repair синхронизирует реплики и обязателен до истечения gc_grace_seconds, иначе удалённые данные могут «воскреснуть». Флаг -pr ограничивает работу primary range и снижает нагрузку. Cleanup запускают после изменения топологии, когда узел перестал владеть частью данных.

Эксплуатация и бэкапы

Снимайте snapshot перед обновлением и храните копии вне кластера. Инкрементальные бэкапы включаются в cassandra.yaml, но snapshot всё равно нужен как точка восстановления. Проверяйте восстановление на отдельном стенде: наличие файлов ещё не означает, что схема и токены совместимы. Для пакетной установки остановка и запуск выполняются через systemd:

nodetool snapshot -t before_upgrade telemetry
nodetool drain
systemctl stop cassandra
systemctl start cassandra

Drain сбрасывает memtable на диск и перестаёт принимать записи; без него остановка может занять больше времени. После старта проверьте nodetool status и tpstats: рост dropped messages указывает на перегрузку координатора.

Диагностика

nodetool status
nodetool tpstats
nodetool netstats
journalctl -u cassandra --since '30 min ago' --no-pager

Ищите узлы в статусе DN, растущие pending compactions, высокий процент tombstones и ошибки в журнале. Для оценки задержек смотрите гистограммы в nodetool tablestats и метрики JVM. Не лечите перегрузку увеличением heap без анализа: слишком большой heap усиливает паузы GC.

Чек-лист перед продакшеном

  • RF не меньше трёх, стойки и дата-центры учтены.
  • Partition key равномерен, размер раздела контролируется.
  • Запросы покрыты таблицами, а не полным сканированием.
  • Настроены repair, snapshots и мониторинг tombstones.
  • Проверено восстановление, а не только создание бэкапа.
  • Есть план роста: добавление узла и перераспределение данных.

Итог

Cassandra даёт масштабируемость ценой дисциплины: данные моделируются под запросы, согласованность выбирается осознанно, а обслуживание включает repair и compaction. Начните с трёх узлов и реалистичной нагрузки, измерьте размер разделов и задержки, и только потом увеличивайте кластер. Если нужны join-ы и транзакции, честно выберите другую базу.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте