4.1 Описание
Apache Cassandra — распределённая система управления базами данных, относящаяся к классу NoSQL-систем и рассчитанная на создание высокомасштабируемых и надёжных хранилищ огромных массивов данных, представленных в виде хэша.

Изначально проект был разработан в недрах Facebook и в 2009 году передан под крыло фонда Apache Software Foundation, эта организация продолжает развитие проекта. Промышленные решения на базе Cassandra развёрнуты для обеспечения сервисов таких компаний, как Cisco, IBM, Cloudkick, Reddit, Digg, Rackspace, Huawei, Netflix, Apple, Instagram, GitHub, Twitter и Spotify. К 2011 году крупнейший кластер серверов, обслуживающий единую базу данных под управлением Cassandra, насчитывал более 400 машин и содержал данные размером более 300 ТБ.
Написана на языке Java, реализует распределённую хэш-систему, сходную с DynamoDB, что обеспечивает практически линейную масштабируемость при увеличении объёма данных. Использует модель хранения данных на базе семейства столбцов, чем отличается от систем, подобных MemcacheDB, которые хранят данные только в связке «ключ — значение», возможностью организовать хранение хэшей с несколькими уровнями вложенности.
Относится к категории отказоустойчивых СУБД: помещённые в базу данные автоматически реплицируются на несколько узлов распределённой сети или даже равномерно распределяются в нескольких дата-центрах. При сбое узла его функции на лету подхватываются другими узлами, добавление новых узлов в кластер и обновление версии Cassandra производится на лету, без дополнительного ручного вмешательства и переконфигурации других узлов.
Тем не менее настоятельно рекомендуется заново сгенерировать ключи (метки) для каждого узла, включая существующие, чтобы сохранить качество распределения нагрузки. Генерации ключей для существующих узлов можно избежать в случае кратного увеличения количества узлов (в 2 раза, в 3 раза и так далее).

4.2 Модель данных
В терминологии кассандры приложение работает с пространством ключей (keyspace), что соответствует понятию схемы базы данных (database schema) в реляционной модели. В этом пространстве ключей могут находиться несколько колоночных семейств (column family), что соответствует понятию реляционной таблицы.
В свою очередь, колоночные семейства содержат колонки (column), которые объединяются при помощи ключа (row key) в записи (row). Колонка состоит из трех частей: имени (column name), метки времени (timestamp) и значения (value). Колонки в пределах записи упорядочены. В отличие от реляционной БД, никаких ограничений на то, чтобы записи (а в терминах БД это строки) содержали колонки с такими же именами, как и в других записях — нет.
Колоночные семейства могут быть нескольких видов, но в этой статье мы будем опускать эту детализацию. Также в последних версиях кассандры появилась возможность выполнять запросы определения и изменения данных (DDL, DML) при помощи языка CQL, а также создавать вторичные индексы (secondary indices).

Конкретное значение, хранимое в кассандре, идентифицируется:
- пространством ключей — это привязка к приложению (предметной области). Позволяет на одном кластере размещать данные разных приложений;
- колоночным семейством — это привязка к запросу;
- ключом — это привязка к узлу кластера. От ключа зависит на какие узлы попадут сохранённые колонки;
- именем колонки — это привязка к атрибуту в записи. Позволяет в одной записи хранить несколько значений.
С каждым значением связана метка времени — задаваемое пользователем число, которое используется для разрешения конфликтов во время записи: чем больше число, тем колонка считается новее, а при сравнении перетирает старые колонки.
4.3 Типы данных
По типам данных: пространство ключей и колоночное семейство — это строки (имена); метка времени — это 64-битное число; а ключ, имя колонки и значение колонки — это массив байтов. Также кассандра имеет понятие типов данных (data type). Эти типы могут по желанию разработчика (опционально) задаваться при создании колоночного семейства.
Для имён колонок это называется сравнителем (comparator), для значений и ключей — валидатором (validator). Первый определяет какие байтовые значения допустимы для имён колонок и как их упорядочить. Второй — какие байтовые значение допустимы для значений колонок и ключей.
Если эти типы данных не заданы, то кассандра хранит значения и сравнивает их как байтовые строки (BytesType) так как, по сути, они сохраняются внутри.
- BytesType: любые байтовые строки (без валидации)
- AsciiType: ASCII строка
- UTF8Type: UTF-8 строка
- IntegerType: число с произвольным размером
- Int32Type: 4-байтовое число
- LongType: 8-байтовое число
- UUIDType: UUID 1-ого или 4-ого типа
- TimeUUIDType: UUID 1-ого типа
- DateType: 8-байтовое значение метки времени
- BooleanType: два значения: true = 1 или false = 0
- FloatType: 4-байтовое число с плавающей запятой
- DoubleType: 8-байтовое число с плавающей запятой
- DecimalType: число с произвольным размером и плавающей запятой
- CounterColumnType: 8-байтовый счётчик
В кассандре все операции записи данных это всегда операции перезаписи, то есть, если в колоночную семью приходит колонка с таким же ключом и именем, которые уже существуют, и метка времени больше, чем та которая сохранена, то значение перезаписывается. Записанные значения никогда не меняются, просто приходят более новые колонки с новыми значениями.
Запись в кассандру работает с большей скоростью, чем чтение. Это меняет подход, который применяется при проектировании. Если рассматривать кассандру с точки зрения проектирования модели данных, то проще представить колоночное семейство не как таблицу, а как материализованное представление (materialized view) — структуру, которая представляет данные некоторого сложного запроса, но хранит их на диске.
Вместо того, чтобы пытаться как-либо скомпоновать данные при помощи запросов, лучше постараться сохранить в коночное семейство все, что может понадобиться для этого запроса. То есть, подходить необходимо не со стороны отношений между сущностями или связями между объектами, а со стороны запросов: какие поля требуются выбрать; в каком порядке должны идти записи; какие данные, связанные с основными, должны запрашиваться совместно — всё это должно уже быть сохранено в колоночное семейство.
Количество колонок в записи ограничено теоретически 2 миллиардами. Это краткое отступление, а подробней — в статье о техниках проектирования и оптимизации. А теперь давайте углубимся в процесс сохранения данных в кассандру и их чтения.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ