Перейти к содержанию

Apache Cassandra

Раздел 02 · Механизмы · Сравнения

Тип материала: архитектурный разбор. Схемы и примеры иллюстративные, если не указано иное.

Область версий: Apache Cassandra 5.0; stable documentation может обновляться. Проверка источников: 2026-11-02.

1. Архитектура и модель данных

FACT. Wide-column partitioned database: keyspace задаёт replication, таблица — partition key и упорядоченные clustering columns. Partition key hash определяет token и replica set; coordinator может быть любым узлом. Query-driven modeling создаёт таблицу под запрос, а не надеется на произвольный JOIN. Commit log не является Kafka-подобным бизнес-журналом replay.

flowchart LR
  Client --> Coordinator
  Coordinator --> R1[Replica commit log and memtable]
  Coordinator --> R2[Replica commit log and memtable]
  R1 --> SST[SSTables and compaction]
  R2 --> SST2[Local SSTables and compaction]
  SST -. anti-entropy repair .-> SST2

2. Физическое хранение и путь записи

Write идёт в commit log и memtable, flush создаёт immutable SSTables. Read объединяет memtable и подходящие SSTables, используя Bloom filters, indexes и timestamps. Bloom false positives добавляют I/O, но false negatives для существующих записей недопустимы. Cassandra 5.0 имеет разные SSTable formats, включая BTI; нельзя сводить все on-disk indexes к одному B-tree.

Compaction переписывает SSTables и удаляет только безопасно очищаемые tombstones. Запас свободного диска и streaming bandwidth нужны до аварии, а не после её возникновения.

Источники механизма: документация 1.

3. Индексы и путь чтения

Partition key ограничивает routing, clustering key — диапазон внутри partition. Запрос по отсутствующему ключу часто требует иной денормализованной таблицы или подходящего индекса. Secondary indexes/SAI имеют отдельную стоимость и ограничения; ALLOW FILTERING не исправляет неверную модель. Unbounded partition делает даже формально допустимый запрос дорогим.

Источники механизма: документация 1, документация 5.

4. Транзакции и consistency guarantees

Обычные операции используют tunable consistency и timestamp conflict resolution, а не serializable SQL-транзакции. Для RF=3 QUORUM требует 2 replicas; R+W>RF даёт пересечение наборов в соответствующем scope, но само по себе не решает concurrent writes и clock skew. LOCAL_QUORUM относится к локальному DC, не глобальному serial order. Conflict resolution обычно действует на cells, поэтому конкурентные mutations могут создать комбинацию значений, не совпадающую с целой строкой любого writer.

LWT через IF использует Paxos и serial consistency для conditional update в поддерживаемой partition scope; стоит дополнительных раундов и конфликтов. SERIAL/LOCAL_SERIAL и обычный write/read CL выполняют разные роли. Не смешивать LWT и обычные записи для одного инварианта, ожидая общей линейризуемости. Logged batch — не распределённая SQL-транзакция с произвольной изоляцией.

Источники механизма: документация 2, документация 5.

5. Репликация, partitioning и sharding

Consistent hashing и vnodes распределяют token ranges; replication strategy определяет DC/rack placement. Adding node вызывает streaming и меняет ownership; repair и topology operations требуют capacity. Native partitioning распределяет partitions по nodes, но не делит горячую partition между несколькими независимыми владельцами записи.

Источники механизма: документация 2.

6. Конкурентная запись и конфликты

Две записи одной ячейки согласуются по timestamps; это не проверка business sequence. Client clock ошибки могут надолго закрепить неверное значение. INSERT с тем же primary key обычно upsert; это не обнаружение несовпадающего payload. Counters имеют специальные ограничения и не становятся идемпотентными от повторения команды; финансовые debit/credit на них не моделировать.

Источники механизма: документация 5.

7. Отказы и восстановление

Commit log replay восстанавливает локальную memtable; replicas, hinted handoff и repair восстанавливают распределённые копии, но hints не заменяют регулярный repair. Timeout означает неизвестный итог записи: retry требует стабильного key/version и осторожности с timestamps/TTL.

Tombstone нельзя удалять раньше безопасного согласования replicas. Недоступная дольше допустимого repair горизонта replica может воскресить старые данные после преждевременного gc. Backup включает snapshots/schema и, для выбранной схемы PITR, commit log archiving; восстановление topology/данных должно быть отрепетировано.

Источники механизма: документация 3, документация 4.

8. Масштабирование и ограничения

Шардировать event partitions по tenant + time bucket + deterministic shard. Bucket ограничивает размер, shard распределяет внутри активного bucket, но чтение tenant-range требует fan-out и merge sorted results. Размер bucket выбирают по bytes/rows, запросам и skew; универсальное «сутки» не является гарантией.

9. Performance trade-offs

LSM оптимизирует последовательный write path ценой read/write/space amplification. Leveled compaction уменьшает overlap при иной write amplification; time-window compaction подходит для временных immutable данных с согласованным TTL. Поздние updates, смешанные TTL и постоянные перезаписи старых windows мешают освобождению целых SSTables.

10. Мониторинг и эксплуатация

nodetool status/tablehistograms/tablestats, compactionstats, tpstats и system metrics: pending compactions, dropped messages, read/write timeouts, partition sizes, tombstones scanned, repair age, disk headroom и coordinator latency. Поддерживать repair schedule, проверять schema agreement и протестированную процедуру замены узла. Не отключать tombstone warnings ради «зелёного» dashboard.

11. Сценарии FinTech и iGaming

INFERENCE. Высокообъёмные immutable events, history запросов антифрода и per-player sessions по известным ключам. Схема High-volume Events задаёт bounded partitions, deterministic routing, remaining TTL и replay. Отдельная OLAP-система нужна для ad-hoc joins/агрегатов.

12. Когда не выбирать

Не выбирать для сложных cross-account инвариантов, многочисленных JOIN и непредсказуемых фильтров. Не использовать LWT как попытку превратить весь кластер в обычную OLTP базу. Объём ingest не компенсирует неверный partition key или недостаточное окно repair.

13. Вопросы на собеседовании

Почему RF=3 + LOCAL_QUORUM не означает global serializability? Кворум локален, а timestamps и параллельные изменения остаются отдельной проблемой.

Почему TTL не равен немедленному освобождению диска? Истечение создаёт логическое удаление; физическое освобождение зависит от compaction и безопасности tombstones.

Можно ли retry counter после timeout? Результат неизвестен, повтор может применить инкремент снова.

14. Практические SQL/config примеры

events.cql показывает schema, TWCS и TTL insert. CQL runtime недоступен: текст проверен на соответствие документации, полноценная server validation не выполнена. Практика: сравнить распределение partitions для одного крупного tenant при одном и нескольких shards; проверить deadline retention после replay.

15. Дополнительные источники

Политика версий и ограничений: реестр.

Типичные ошибки проектирования

Неограниченный player partition; ALLOW FILTERING вместо модели; timestamp как business ordering; gc tombstones без repair; replay с новым полным TTL.

Практические упражнения

Оцените rows и bytes самой горячей partition по заданной вами нагрузке; выберите bucket и shards, рассчитайте fan-out одного запроса.