Cassandra
Разработчику
Аналитику
Тестировщику
Архитектору
Инженеру
Cassandra
Apache Cassandra — это распределённая, децентрализованная, open-source система управления данными, относящаяся к классу wide-column stores (ширококолоночных хранилищ) в рамках фамилии NoSQL-решений. Она была спроектирована с нуля для обеспечения высокой доступности, линейной масштабируемости и отказоустойчивости даже в условиях выхода из строя целых дата-центров. Ключевая особенность Cassandra — её архитектура без единой точки отказа — в кластере нет выделенного мастера, все узлы равноправны и могут обслуживать как операции чтения, так и записи. Эта модель, известная как masterless architecture, позволяет Cassandra функционировать без перерывов даже при потере значительной части инфраструктуры, при этом гарантируя сохранность данных.
Cassandra не является ни улучшенной реляционной СУБД, ни упрощённым key-value хранилищем. Это самостоятельная парадигма, возникшая в ответ на конкретные требования высоконагруженных систем, в первую очередь — Facebook (где Cassandra и была разработана в 2008 году как часть инфраструктуры почтового сервиса). В 2010 году проект был передан Apache Software Foundation и с тех пор развивается как полностью независимый open-source продукт, управляемый сообществом и корпоративными участниками (в частности, DataStax, ScyllaDB, Instaclustr и другими).
Play ITЗагрузка интерактивного демо…
Контекст
Для понимания места Cassandra в экосистеме СУБД необходимо рассмотреть эволюцию требований к системам хранения данных. Традиционные реляционные базы данных (PostgreSQL, MySQL, Oracle) великолепно справляются с работой в рамках одного сервера — обеспечивают строгую целостность (ACID), поддерживают сложные связи между сущностями, транзакции, JOIN’ы и декларативные запросы. Однако при попытке масштабирования за пределы одного узла они сталкиваются с фундаментальными ограничениями — горизонтальное масштабирование затруднено, репликация часто асинхронна и может приводить к расхождениям, а централизованная архитектура создаёт узкие места и точки отказа.
Парадигма NoSQL возникла как реакция на потребности веб-гигантов (Google, Amazon, Facebook), которым требовались системы, способные:
- обрабатывать миллиарды операций в секунду;
- хранить экза- и зеттабайты данных;
- выдерживать отказы оборудования без простоев;
- обеспечивать низкие задержки даже при географически распределённой инфраструктуре;
- поддерживать "мягкую" схему данных, допускающую эволюцию структуры без дорогостоящих миграций.
В рамках NoSQL выделяют четыре основные модели данных:
- Key-Value (Redis, DynamoDB);
- Document (MongoDB, Couchbase);
- Graph (Neo4j, JanusGraph);
- Wide-Column (Cassandra, ScyllaDB, HBase).
Cassandra относится к последней группе. Её отличительная черта — организация данных по колонкам, причём не в том смысле, в каком это делает, например, ClickHouse (речь о котором пойдёт в отдельной главе), а в виде гибкой, иерархической структуры, где строки могут иметь различный набор атрибутов, а физическое хранение данных оптимизировано под последовательное чтение целых столбцов или групп столбцов.
На уровне реализации данные группируются в sstables, и внутри них информация упорядочена по partition key, затем по clustering key, что позволяет эффективно обрабатывать запросы, фильтрующие по первичному ключу и его компонентам. Термин "колоночная" здесь отражает логическую модель данных — хотя и физическое хранение всё же использует преимущества колоночного доступа при сканировании sstable’ов.
Логическая модель данных
Cassandra оперирует понятием keyspace — аналогом схемы (schema) в реляционных СУБД. Каждый keyspace содержит одну или несколько таблиц (ранее называвшихся column families), но эти таблицы принципиально отличаются от SQL-таблиц.
В реляционной модели таблица — это строгий набор строк фиксированной структуры: каждая строка содержит одинаковый набор столбцов, определённый в DDL. В Cassandra таблица — это упорядоченное множество строк, в каждой из которых может быть различное количество атрибутов, причём структура определяется через первичный ключ и дополнительные столбцы, которые могут быть опущены.
Каждая строка идентифицируется разделительным ключом (partition key). Это может быть один столбец или комбинация столбцов (composite key). Все данные, принадлежащие одной партиции (то есть имеющие одинаковое значение partition key), хранятся физически рядом — на одном или нескольких узлах кластера, в зависимости от стратегии репликации. Внутри партиции строки дополнительно упорядочиваются по ключу кластеризации (clustering key) — ещё одному набору столбцов, который задаёт сортировку внутри партиции.
Пример:
CREATE TABLE user_events (
user_id UUID,
event_time TIMESTAMP,
event_type TEXT,
payload TEXT,
PRIMARY KEY (user_id, event_time)
) WITH CLUSTERING ORDER BY (event_time DESC);
Здесь:
user_id— partition key;event_time— clustering key;- В рамках одной партиции (например,
user_id = 'a1b2c3d4-e89b-12d3-a456-426614174000') строки будут храниться упорядоченно по убыванию времени события; - Для одного
user_idможет быть сколько угодно событий — новых строк, каждая со своимevent_time; - У разных пользователей может быть совершенно разное количество событий — от нуля до миллиардов;
- Столбцы могут отсутствовать в конкретной строке (разреженные данные), но новый столбец нужно объявить в схеме через
ALTER TABLE ... ADD— без этого CQL вернётUndefined column name.
Такая гибкость достигается за счёт отказа от строгой нормализации и межстрочных связий. В Cassandra данные дублируются намеренно: одна и та же сущность может храниться в нескольких таблицах с разной структурой, оптимизированной под конкретные запросы. Это называется денормализацией. Здесь проектирование базы данных начинается с запросов — сначала определяют, какие операции будут выполняться, затем — как устроить таблицы, чтобы каждый запрос обращался к одной партиции (или минимальному их числу). JOIN’ы, подзапросы и транзакции, охватывающие несколько партиций — отсутствуют по дизайну.
Таблица — запрос приложения и первичный ключ
Правило: в WHERE обязательно должен фигурировать полный partition key (все его столбцы). Clustering columns задают сортировку внутри партиции и позволяют диапазоны (>, <) только после partition key.
| Запрос приложения | Таблица | PRIMARY KEY | Эффективный CQL |
|---|---|---|---|
| Все события пользователя за период | user_events | (user_id, event_time) | WHERE user_id = ? AND event_time >= ? AND event_time < ? |
| Последние N событий пользователя | user_events | (user_id, event_time DESC) | тот же partition key + ORDER BY не нужен, если clustering DESC |
| Сотрудники одного отдела | employees_by_dept | (department_id, employee_id) | WHERE department_id = ? |
| Поиск по email без partition key | отдельная emails_lookup | (email) | WHERE email = ? → получить employee_id, затем основная таблица |
| "Все активные пользователи" без ключа | — | — | Плохо: ALLOW FILTERING / full scan — нужна другая таблица под этот запрос |
Если запрос не укладывается в одну строку таблицы — создают вторую таблицу с другим partition key (query-driven modelling), а не пытаются "натянуть" SQL-привычку SELECT … WHERE status = 'active' на одну универсальную таблицу.
Горячие партиции и размер партиции
Все строки с одним partition key хранятся физически рядом. Если один ключ получает непропорционально много записей (популярный пользователь, один датчик с миллиардами событий), возникает hot partition — узел перегружается, latency растёт.
Ориентиры:
- держать партицию до ~100 МБ (практическое правило, не жёсткий лимит);
- для time-series добавлять bucketing в partition key:
(user_id, day)вместо одногоuser_id; - избегать partition key с низкой кардинальностью (
status = 'active'→ одна гигантская партиция).
-- Плохо: все события одного пользователя в одной партиции без границ
PRIMARY KEY (user_id, event_time)
-- Лучше для длинной истории: bucket по дню
PRIMARY KEY ((user_id, day), event_time)
Пример второй таблицы под другой доступ:
-- Запрос: события по типу за день (другой partition key)
CREATE TABLE events_by_type_day (
event_type TEXT,
day DATE,
event_time TIMESTAMP,
user_id UUID,
payload TEXT,
PRIMARY KEY ((event_type, day), event_time)
) WITH CLUSTERING ORDER BY (event_time DESC);
Архитектура
Cassandra реализует модель peer-to-peer (P2P). Каждый узел (node) в кластере знает о других узлах через механизм gossip protocol — лёгкое, периодическое обменное взаимодействие, в ходе которого узлы обмениваются информацией о своём состоянии, о состоянии других узлов и о топологии кластера. Это позволяет кластеру динамически адаптироваться: узел может быть добавлен или удалён без остановки системы и без перенастройки клиентов.
Данные распределяются по узлам с помощью consistent hashing с применением partitioner (по умолчанию — Murmur3Partitioner). Пространство ключей (token ring) делится на диапазоны; в современных кластерах по умолчанию используются vnodes (virtual nodes) — каждый физический узел владеет множеством небольших диапазонов, что упрощает добавление и удаление машин без "горячих" сегментов.
Путь записи (write path):
При записи координатор сначала фиксирует данные в commit log (на диск, для durability) и memtable (в оперативную память, для скорости). Когда memtable достигает порога, она сбрасывается на диск в виде SSTable — неизменяемых (immutable), упорядоченных файлов. Со временем SSTable компактифицируются (compaction), чтобы удалить дубликаты и устаревшие версии записей (в том числе — помеченные как удалённые, tombstones).
Tombstones, DELETE и TTL
DELETE в Cassandra не стирает данные мгновенно — создаёт tombstone (маркер удаления). При чтении tombstones учитываются; при compaction — удаляются, но только после gc_grace_seconds (по умолчанию 10 дней) и регулярного nodetool repair.
Практика:
- для временных данных предпочитайте TTL вместо массовых
DELETE; - частые удаления внутри одной партиции → рост tombstones →
TombstoneOverwhelmingException; gc_grace_secondsдолжно быть не меньше интервала между repair-сессиями.
Репликация производится на основе replication factor (RF) — числа копий данных, которые должны храниться в кластере. Например, RF = 3 означает, что каждая партиция будет храниться на трёх узлах. Выбор узлов для репликации определяется replication strategy: SimpleStrategy (для одного дата-центра) или NetworkTopologyStrategy (для нескольких дата-центров, с контролем количества реплик в каждом). Это позволяет размещать реплики так, чтобы выдержать отказ целого дата-центра без потери данных и доступности.
Уровни консистентности (Consistency Level)
В Cassandra consistency level задаётся на каждый запрос (в драйвере или в cqlsh). Он определяет, сколько реплик должно ответить, чтобы операция считалась успешной. Это компромисс latency ↔ свежесть данных.
| Уровень | Запись / чтение | Когда использовать |
|---|---|---|
ONE | Минимум одна реплика | Максимальная скорость; допустимо устаревшее значение |
LOCAL_ONE | Одна реплика в локальном ДЦ | То же, но без меж-ДЦ RTT |
QUORUM | Большинство реплик партиции: floor(RF/2)+1 | Баланс для production при RF=3 |
LOCAL_QUORUM | Кворум в локальном ДЦ | Типичный выбор при NetworkTopologyStrategy |
ALL | Все реплики | Строго, но хрупко при отказе одного узла |
SERIAL / LOCAL_SERIAL | Линейлизуемость для LWT | Условные записи (IF NOT EXISTS) |
Правило кворума (упрощённо): при RF = 3 кворум = 2. Чтобы чтение с высокой вероятностью увидело последнюю запись, часто выбирают QUORUM и на запись, и на чтение. Класическая формула для согласованного чтения: W + R > RF (где W и R — число подтверждающих реплик при write и read). Это tunable consistency, не linearizability как в SQL; для атомарности одной строки — LWT с SERIAL.
Last-Write-Wins и конфликты версий
При одновременной записи в одну ячейку Cassandra выбирает версию с большим timestamp (Last-Write-Wins). Конфликты не разрешаются на уровне приложения — важно синхронизировать часы на клиентах или явно задавать USING TIMESTAMP при backfill. Для "вставить только если нет" — LWT (IF NOT EXISTS), не обычный INSERT.
Пример в cqlsh (после подключения к кластеру):
CONSISTENCY LOCAL_QUORUM;
INSERT INTO user_events (user_id, event_time, event_type)
VALUES (uuid(), toTimestamp(now()), 'login');
CONSISTENCY ONE;
SELECT event_type FROM user_events WHERE user_id = ? LIMIT 10;
SERIAL нужен для lightweight transactions — например, вставка email только если его ещё нет:
INSERT INTO emails_lookup (email, user_id)
VALUES ('anna@example.com', ...)
IF NOT EXISTS;
Не путать с ACID-транзакциями SQL: LWT в Cassandra — атомарность одной строки при согласовании через Paxos, с заметной ценой по latency.
Такой подход позволяет гибко балансировать между скоростью, доступностью и строгостью (Cassandra в целом тяготеет к AP, но уровни QUORUM / SERIAL приближают поведение к C там, где это нужно бизнесу).
Экосистема и инструментарий Apache Cassandra
Apache Cassandra — это ядро СУБД и зрелая экосистема, включающая официальные и сообщественные инструменты для развертывания, мониторинга, администрирования, интеграции и разработки. Экосистема формировалась в течение более чем десяти лет и включает как open-source, так и коммерческие решения.
Ядро Apache Cassandra и его развитие
Основной дистрибутив — Apache Cassandra — поддерживается Apache Software Foundation. Это полностью open-source проект с лицензией Apache 2.0. Развитие происходит через процесс Apache Community Development: предложения вносятся в виде CASSANDRA JIRA тикетов, обсуждаются на mailing lists и принимаются после ревью коммиттеров. С момента выхода Cassandra 4.0 в 2021 году была значительно усилена стабильность, безопасность (поддержка SSL/TLS на уровне клиента и сервера, аудит-логгирование), производительность (Zero Copy Streaming для быстрой перебалансировки) и тестируемость (включая воспроизведение production-нагрузок через fqltool).
Важно отметить, что Cassandra следует принципу long-term stability: новые функции вносятся осторожно, с акцентом на обратную совместимость. Согласно текущей политике, одновременно поддерживаются до четырёх основных версий (например, 3.11.x, 4.0.x, 4.1.x, 5.0.x), что даёт предприятиям гибкость при планировании обновлений.
Дистрибутивы и платформы на основе Cassandra
Помимо "голого" Apache Cassandra, существуют производные реализации и управляемые сервисы:
-
DataStax Astra DB — fully managed серверлесс-сервис Cassandra-as-a-Service, совместимый с CQL, с REST/gRPC API, встроенной аутентификацией и веб-интерфейсом. Позволяет запускать кластеры в облаках AWS, GCP и Azure без управления инфраструктурой. Поддерживает Vector Search (начиная с 2024 г.), что расширяет применение Cassandra в ML-сценариях.
-
ScyllaDB — drop-in замена Cassandra на C++, переписанная с нуля с акцентом на максимальную производительность. Использует асинхронную архитектуру Seastar, что позволяет добиваться в разы большей пропускной способности при меньшей задержке. Сохраняет совместимость с CQL, SSTable-форматом и большинством драйверов. Особенно эффективна на современных SSD/NVMe и многопроцессорных системах.
-
K8ssandra — проект, объединяющий Cassandra с Kubernetes. Включает Helm-чарты, оператор Cassandra, инструменты мониторинга (Prometheus, Grafana), резервного копирования (Medusa), восстановления и управления. Позволяет разворачивать Cassandra-кластеры как cloud-native приложения.
-
Instaclustr, Aiven, Amazon Keyspaces (for Apache Cassandra) — управляемые сервисы от сторонних провайдеров. Keyspaces, например, предлагает API-совместимость с Cassandra, но не использует исходный код Apache Cassandra — это проприетарная реализация от AWS, оптимизированная под их инфраструктуру.
Эти решения расширяют применение в разных контекстах: от bare-metal кластеров до serverless-архитектур.
Инструменты администрирования и разработки
Хотя базовый интерфейс Cassandra — консольный (cqlsh), на практике разработчики и администраторы используют графические и скриптовые инструменты.
cqlsh — официальная консоль Cassandra Query Language
cqlsh — это Python-клиент, поставляемый с дистрибутивом Cassandra. Он предоставляет интерактивную оболочку для выполнения CQL-команд, просмотра метаданных (DESCRIBE KEYSPACES, DESCRIBE TABLE users), выполнения запросов и отладки. Поддерживает подсветку синтаксиса, автодополнение и историю. Для продвинутых сценариев используется в скриптах (cqlsh -f script.cql).
Графические клиенты
-
DataStax DevCenter (устаревший, но всё ещё используемый) — desktop-приложение с поддержкой подключения к нескольким кластерам, визуальным редактором схем, профилированием запросов и историей выполнения. Совместим с Apache Cassandra, не требует DataStax Enterprise.
-
DBeaver — универсальный SQL-клиент с поддержкой Cassandra через официальный Java-драйвер. Поддерживает просмотр структуры keyspace’ов, выполнение запросов, экспорт данных. Удобен при работе с гетерогенной инфраструктурой (PostgreSQL + Cassandra + Kafka и т.д.).
-
Cassandra Reaper — open-source инструмент для управления repair — фоновым процессом синхронизации реплик, критически важным для консистентности в распределённой системе. Позволяет планировать, мониторить и приостанавливать repair-сессии с веб-интерфейсом.
-
Prometheus + Grafana + Cassandra Exporter — стандартный стек для мониторинга. Cassandra предоставляет JMX-метрики; экспортер преобразует их в формат Prometheus. Готовые дашборды от сообщества отслеживают — latency, throughput, compaction backlog, cache hit ratio, thread pool utilisation и другие ключевые показатели.
-
Medusa — инструмент для бэкапа и восстановления на основе snapshot’ов и sstable-копирования. Поддерживает интеграцию с облаками (S3, GCS), шифрование, инкрементальные бэкапы.
Программные интерфейсы
Для интеграции Cassandra в приложения используются официальные и third-party драйверы. Все они реализуют протокол Cassandra Native Protocol (начиная с v1 в 2012 г., сейчас актуален v5/v6), который бинарный, асинхронный и поддерживает connection pooling, подготовленные запросы, устойчивость к отказам.
Официальные драйверы (DataStax)
DataStax, несмотря на коммерческую ориентацию, поддерживает open-source драйверы, которые совместимы с Apache Cassandra:
-
Java Driver (
com.datastax.oss:java-driver-core) — эталонная реализация. Поддерживает реактивные стримы (Reactor, RxJava), автоматическое обнаружение топологии кластера, политики retry и speculative execution. Интегрируется с Spring через Spring Data Cassandra, предоставляя шаблонный доступ (CassandraTemplate) и репозитории (CrudRepository-аналоги). -
Python Driver (
cassandra-driver) — асинхронный (черезasyncioилиgevent) и синхронный интерфейсы. Поддерживает подготовленные запросы, connection pooling, автоматическую маршрутизацию по локальным дата-центрам. -
Node.js Driver (
@datastax/cassandra-driver) — построен наasync/await, поддерживает streaming-результатов, политики балансировки нагрузки. -
C#/.NET Driver (
CassandraCSharpDriver) — полностью async/await, с поддержкой LINQ-подобных выражений черезLinqProvider.
Все драйверы реализуют token-aware routing — запрос направляется непосредственно на узел, ответственный за нужную партицию, минуя промежуточные ноды — это снижает latency и нагрузку на сеть.
Альтернативные и сообщественные драйверы
- gocql — популярный драйвер для Go, высокооптимизированный, с поддержкой кастомных типов и tracing’а.
- php-driver — расширение на C для PHP, с интерфейсом, близким к PDO.
- rust-cassandra-driver — нативная реализация на Rust, активно развивается, подходит для high-performance микросервисов.
Важный момент: драйверы не эмулируют SQL-семантику. Они работают строго в рамках возможностей Cassandra: отсутствие JOIN’ов, ограничения на фильтрацию (только по компонентам первичного ключа без ALLOW FILTERING), отсутствие глобальных транзакций.
Cassandra Query Language (CQL) — SQL-подобный, но не SQL
CQL — это декларативный язык запросов, разработанный специально для Cassandra. Он сознательно сделан похожим на SQL, чтобы снизить порог входа для разработчиков с реляционным опытом. Однако это аналогия на синтаксическом уровне, а не семантическая совместимость.
Синтаксические параллели и ключевые различия
| Конструкция | В SQL (PostgreSQL/MySQL) | В CQL (Cassandra) |
|---|---|---|
| Создание схемы | CREATE SCHEMA или CREATE DATABASE | CREATE KEYSPACE |
| Таблица | CREATE TABLE users (id INT PRIMARY KEY, ...) | CREATE TABLE users (id UUID, ..., PRIMARY KEY (id)) |
| Первичный ключ | Может быть составным, но не управляет физ. расположением | Обязательно состоит из PARTITION KEY + (опц.) CLUSTERING COLUMNS; определяет, как данные распределяются и сортируются |
| SELECT | Поддерживает JOIN, подзапросы, оконные функции | Только одна таблица. Фильтрация — только по компонентам первичного ключа (или через ALLOW FILTERING, что не рекомендуется). Нет подзапросов. |
| UPDATE/DELETE | Может затрагивать любые строки по WHERE | Без WHERE, содержащего полный PARTITION KEY, операция недопустима (или требует ALLOW FILTERING с риском full scan) |
| Транзакции | BEGIN; … COMMIT; с ACID-гарантиями | Нет multi-row транзакций. Есть lightweight transactions (LWT) на основе Paxos — IF NOT EXISTS, IF column = value, но с высокой latency и нагрузкой |
| Индексы | B-tree, Hash, GiST, GIN и т.д. | Вторичные индексы (CREATE INDEX) — только по одному столбцу; при высокой кардинальности неэффективны; MV устарели; рекомендуется денормализация |
Пример типичного CQL-запроса:
SELECT event_type, payload
FROM user_events
WHERE user_id = 'a1b2c3d4-e89b-12d3-a456-426614174000'
AND event_time > '2025-01-01 00:00:00+0000'
AND event_time < '2025-02-01 00:00:00+0000';
Здесь:
user_id— partition key → запрос идёт к конкретной партиции;event_time— clustering key → фильтрация внутри партиции выполняется эффективно (по упорядоченному индексу);- Ответ возвращается в порядке, заданном
CLUSTERING ORDER BY.
Если попытаться выполнить:
SELECT * FROM user_events WHERE event_type = 'login';
— запрос завершится ошибкой, если не добавить ALLOW FILTERING. С этой опцией он выполнится, но будет сканировать все партиции — что на кластере в миллионы строк может занять часы и убить производительность. Это демонстрирует фундаментальный принцип: модель данных строится под запросы, а не наоборот.
Batch и оператор IN
Batch (BEGIN BATCH … APPLY BATCH) — не SQL-транзакция:
LOGGED BATCH— атомарность только если все строки в одной партиции; иначе координация без гарантии "всё или ничего";UNLOGGED BATCH— группировка для удобства клиента, без атомарности между партициями.
IN по partition key читает несколько партиций (допустимо для малого списка id). IN по clustering column — только внутри одной партиции, когда partition key задан полностью.
Сравнение с другими системами хранения — где Cassandra уместна — и где нет
| Критерий | Cassandra | PostgreSQL / MySQL | ClickHouse | MongoDB |
|---|---|---|---|---|
| Модель данных | Wide-column (гибкие партиции) | Relational (строгая схема) | Columnar (реляционная, но физически — колонки) | Document (BSON, вложенные структуры) |
| Архитектура | Masterless, P2P | Master-replica / Patroni / Citus | Distributed (шардирование + репликация) | Replica set / Sharded cluster |
| Консистентность по умолчанию | Tuneable (ONE, QUORUM, ALL) | Strong (ACID) | Eventual (но с фоновой repair’кой) | Strong (в рамках replica set) |
| Запись vs Чтение | Оптимизирована под запись | Сбалансирована | Оптимизирована под агрегацию и чтение | Сбалансирована |
| Масштабирование | Линейное, горизонтальное, без downtime | Сложное (шардирование — отдельный слой) | Линейное, но с ограничениями на UPDATE/DELETE | Горизонтальное (шарды) |
| Поддержка JOIN’ов | Нет | Полная | Поддержка, но неэффективна | Lookup’ы через $lookup, но локально |
| Гео-репликация | Встроенная, на уровне стратегии | Через логическую репликацию / BDR | Нет в core; требуется внешний оркестратор | Поддержка multi-region |
| Типичные сценарии | Логирование, IoT, телеметрия, инвентарь, временные ряды (с ограничениями) | OLTP, финансовые системы, ERP | OLAP, аналитика, отчёты в реальном времени | Контент, каталоги, пользовательские профили |
Важное уточнение по ClickHouse:
ClickHouse — это реляционная СУБД с колоночным физическим хранением. Она поддерживает SQL (в расширенном диалекте), JOIN’ы, подзапросы, но оптимизирована для massive parallel reads и агрегации. В отличие от Cassandra, в ClickHouse:
- данные не предназначены для частых UPDATE/DELETE (изменения — фоновые, пакетные);
- первичный ключ — для сортировки на диске (sparse index);
- нет встроенной отказоустойчивости "из коробки" — репликация требует кластерной настройки.
Таким образом, Cassandra и ClickHouse решают разные задачи: первая — для записи и хранения потоков событий с гарантией доступности; вторая — для анализа этих событий позже.
Типичные сценарии применения Cassandra
Cassandra наиболее эффективна в доменах, где доминируют следующие требования:
-
Высокая скорость записи с гарантией durability
Пример: телеметрия IoT-устройств. Датчики отправляют миллионы событий в секунду. Каждое событие — строка в таблицеsensor_readings(partition_key = sensor_id, clustering_key = timestamp). Cassandra принимает поток без бутылочных горлышек, даже при выходе из строя части узлов. -
Глобальная доступность и tolerance к сетевым разрывам
Пример: мессенджер или социальная сеть с пользователями по всему миру. Репликация настраивается так — 2 копии в Европе, 2 — в США, 2 — в Азии (RF = 6). При обрыве трансатлантического кабеля пользователи в Азии продолжают работать — их данные локально доступны. -
Хранение временных рядов с высокой кардинальностью
Пример: метрики приложений (latency, error rate по микросервисам). Модельmetrics(service, host, timestamp) PRIMARY KEY ((service, host), timestamp)позволяет эффективно выбирать "все метрики за час по сервису X на хосте Y". Важно: Cassandra не заменяет TimescaleDB или InfluxDB для сложных временных запросов, но отлично подходит для "сырых" данных. -
Каталоги и инвентарные системы
Пример: реестр устройств в телеком-сети (миллионы SIM-карт, роутеров). Записи редко изменяются, но часто читаются. Денормализация позволяет хранить одну сущность в нескольких представлениях — поiccid, поmsisdn, поcustomer_id— без JOIN’ов. -
Сессионные хранилища и кэши с персистентностью
Пример: распределённый сессионный store для stateless-микросервисов. TTL (time-to-live) на уровне столбца позволяет автоматически удалять устаревшие сессии.
Где Cassandra не рекомендуется
- OLTP-системы с жёсткими требованиями к транзакциям (банковские переводы, бухгалтерия);
- Приложения, где доминируют сложные JOIN’ы и ad-hoc аналитические запросы;
- Системы с низким объёмом данных — накладные расходы на кластер не оправданы;
- Сценарии, требующие полнотекстового поиска — лучше интегрировать с Elasticsearch, а не пытаться эмулировать его в Cassandra.