«Возьмём Cassandra, она же масштабируется» — фраза, за которой часто нет понимания, чем Cassandra отличается от привычной базы и какой ценой даётся её масштаб. Cassandra решает вполне конкретный класс задач и в других делает только хуже. Разберём, что она такое, и сравним с двумя другими популярными вариантами — реляционной PostgreSQL и документной MongoDB (их сравнение между собой — в отдельной статье). Это статья про выбор; подробный разбор устройства Cassandra — в отдельном разделе.
Что такое Cassandra
Apache Cassandra — это колоночная (wide-column) распределённая NoSQL-база данных. Она выросла из двух идей: модель данных взята у Google Bigtable, а способ распределения по узлам — у Amazon Dynamo. Отсюда две её определяющие черты:
- Модель данных «широкая строка». Данные лежат в таблицах с языком запросов CQL, но устроены иначе, чем в реляционной базе: по ключу раздела (partition key) хранится группа строк, сгруппированных и упорядоченных колонками кластеризации. Одна партиция может содержать от одной до миллионов упорядоченных строк — это и называют wide-column. Проектируют такие таблицы не «от сущностей», а от запросов.
- Отсутствие главного узла (masterless). В кластере Cassandra все узлы равноправны — нет ведущего, к которому идут все записи. Данные распределены по кольцу по хешу ключа раздела, каждый узел принимает и чтение, и запись. Это и даёт её главное свойство.
Главное свойство — линейная горизонтальная масштабируемость записи. Добавили узлы — пропорционально выросла пропускная способность, без единой точки, в которую упирается нагрузка. Плюс встроенная репликация по нескольким дата-центрам в режиме «активный-активный»: кластер продолжает принимать запись, даже если целый дата-центр отвалился.
Cassandra против PostgreSQL
PostgreSQL — реляционная база с одним первичным узлом на запись. Её сила — строгая схема, JOIN между таблицами, произвольные запросы и ACID-транзакции: перевод денег между счетами либо проходит целиком, либо не проходит вовсе.
Cassandra устроена ровно наоборот там, где это нужно для масштаба:
- Нет
JOINи произвольных запросов. Запрос должен бить по ключу раздела; «а покажи теперь под другим углом» не работает без заранее спроектированной под этот угол таблицы. - Нет полноценных транзакций между строками. Есть облегчённые условные операции, но переводить деньги между счетами, как в PostgreSQL, здесь нельзя.
- Согласованность настраивается на каждый запрос. Cassandra не «всегда несогласованная»: уровень согласованности задают отдельно для чтения и записи. Читаете и пишете с одной репликой — быстро, но чтение может ненадолго отставать (итоговая согласованность). Читаете и пишете с кворумом — получаете строгое чтение (правило
R + W > RF), но с большей задержкой. Это осознанный выбор баланса скорости и свежести, а не жёсткая жертва согласованностью.
Вывод: PostgreSQL берут, когда важны транзакции, связи и гибкие запросы на данных, помещающихся на один мощный сервер (плюс реплики для чтения). Cassandra — когда объём записи и требование «всегда доступна» перерастают то, что тянет один первичный узел.
Cassandra против MongoDB
MongoDB — документная база: данные хранятся как JSON-подобные документы с гибкой схемой. Обе — NoSQL и обе умеют масштабироваться шардированием, но природа разная:
- Топология. У MongoDB есть первичный узел на каждый шард (replica set с автоматическим переключением при сбое). У Cassandra первичного узла нет вообще — запись принимает любой узел. Для сценария «активная запись в нескольких регионах одновременно» Cassandra устроена удобнее.
- Запросы и индексы. MongoDB богаче: вторичные индексы, гибкие запросы по полям, агрегации, многодокументные транзакции. Cassandra в запросах жёстче — всё вокруг ключа раздела.
- Ниша. MongoDB — универсальная база под изменчивую предметную область и разнообразные запросы. Cassandra — узкий инструмент под огромный поток записи и постоянную доступность.
Если упрощать: MongoDB гибче в модели и запросах, Cassandra — сильнее в масштабе записи и мультирегиональной доступности.
Модель данных: сначала запросы, потом таблицы
Главная ошибка новичка в Cassandra — проектировать таблицы как в реляционной базе, «по сущностям», а потом удивляться, что нужный запрос невозможен. В Cassandra проектирование идёт от запросов: сначала выписывают, какие именно чтения будут в продакшене, и под каждое строят свою таблицу, сознательно дублируя данные (денормализация — норма, а не грех). Ключ раздела (partition key) определяет, на каком узле лежат данные и по какому ключу их можно достать; колонки кластеризации задают порядок внутри раздела.
Отсюда практическое правило: если заранее не известно, как будут спрашивать данные, или запросы разнообразны и меняются — Cassandra противопоказана. Она вознаграждает предсказуемые обращения по ключу и наказывает за произвольную аналитику.
Сравнение
| PostgreSQL | MongoDB | Cassandra | |
|---|---|---|---|
| Модель | реляционная (таблицы) | документная (JSON) | колоночная (широкая строка) |
| Схема | строгая | гибкая | полустрогая, под запросы |
| Топология записи | один первичный узел | первичный на шард | без главного узла |
| Транзакции | полный ACID | на документ и многодок. | ограниченные |
JOIN/произвольные запросы | да | ограниченно | нет |
| Согласованность | строгая | настраиваемая | настраиваемая, по умолчанию итоговая |
| Сильна в | связи, транзакции, аналитика | гибкая модель, разные запросы | огромный поток записи, постоянная доступность |
Когда что брать
- PostgreSQL — выбор по умолчанию: связи, транзакции, гибкие запросы, данные на одном сервере. Большинству сервисов её хватает надолго.
- MongoDB — изменчивая предметная область, документная модель, разнообразные запросы; нужен горизонтальный рост, но не экстремальный поток записи.
- Cassandra — телеметрия и события интернета вещей, ленты активности, логи, счётчики, сообщения: огромный поток записи, предсказуемые обращения по ключу, требование «всегда доступна» и запись в нескольких регионах сразу.
Типичные ошибки
- Берут Cassandra «ради масштаба» без потока записи. Для сервиса на один сервер это лишь потеря транзакций,
JOINи гибких запросов взамен ненужного масштаба. - Проектируют таблицы Cassandra как реляционные. Без проектирования от запросов нужные чтения оказываются невозможны или дороги.
- Ждут от Cassandra транзакций и аналитики. Перевод денег и произвольные отчёты — не её задача; для этого рядом держат PostgreSQL.
- Путают «NoSQL» с «современно». MongoDB и Cassandra — разные инструменты под разные задачи, а не modнее реляционной базы.
Коротко
- Cassandra — колоночная распределённая NoSQL без главного узла; её конёк — линейная масштабируемость записи и постоянная доступность, в том числе в нескольких дата-центрах.
- В отличие от PostgreSQL, у неё нет полноценных транзакций,
JOINи произвольных запросов; согласованность по умолчанию итоговая. - В отличие от MongoDB, у неё нет первичного узла и она сильнее в потоке записи, но жёстче в модели и запросах.
- Таблицы Cassandra проектируют от запросов, сознательно дублируя данные.
- Ниша Cassandra узкая: телеметрия, события, логи, счётчики — большой поток записи и предсказуемые обращения по ключу. Для связей, транзакций и аналитики берут PostgreSQL.