Язык запросов в cassandra

7) Язык запросов (CQL)

В этой статье вы узнаете

Вставить данные

Команда «Вставить в» записывает данные в столбцы Кассандры в виде строк. Он будет хранить только те столбцы, которые предоставлены пользователем. Вы должны обязательно указать только столбец первичного ключа.

Это не займет места для не заданных значений. Результаты не возвращаются после вставки.

Синтаксис

пример

Вот снимок выполненной команды «Вставить в», которая вставит одну запись в таблицу Кассандры «Студент».

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

После успешного выполнения команды «Вставить в» одна строка будет вставлена ​​в таблицу Cassandra Student с RollNo 2, именем Michael, отделом CS и Semester 2.

Вот снимок текущего состояния базы данных.

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

Upsert Data

Кассандра расстается. Upsert означает, что Cassandra вставит строку, если первичный ключ еще не существует, в противном случае, если первичный ключ уже существует, он обновит эту строку.

Обновить данные

Команда «Обновить» используется для обновления данных в таблице Cassandra. Если после обновления данных результаты не возвращаются, это означает, что данные успешно обновлены, в противном случае будет возвращена ошибка. Значения столбцов изменяются в предложении «Set», а данные фильтруются с помощью предложения «Where».

Синтаксис

пример

Вот скриншот, который показывает состояние базы данных перед обновлением данных.

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

Вот снимок выполненной команды «Обновить», которая обновляет запись в таблице Student.

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

После успешного выполнения команды «Обновить студента», имя студента изменится с «Кларк» на «Хайден» с номером 1.

Вот скриншот, который показывает состояние базы данных после обновления данных.

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

Кассандра Удалить данные

Команда «Удалить» удаляет всю строку или несколько столбцов из таблицы Student. Когда данные удаляются, они не удаляются из таблицы сразу. Вместо этого удаленные данные помечаются надгробной плитой и удаляются после уплотнения.

Синтаксис

Приведенный выше синтаксис удалит одну или несколько строк в зависимости от фильтрации данных в предложении where.

Приведенный выше синтаксис удалит некоторые столбцы из таблицы.

пример

Вот снимок, который показывает текущее состояние базы данных перед удалением данных.

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

Вот снимок команды, которая удалит одну строку из таблицы Student.

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

После успешного выполнения команды «Удалить» одна строка будет удалена из таблицы Student, где значение rollno равно 1.

Вот снимок, который показывает состояние базы данных после удаления данных.

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

Что Кассандра не поддерживает

Существуют следующие ограничения в языке запросов Cassandra (CQL).

Данные фильтруются по имени столбца. Получены все записи, имя которых равно Guru99.

Источник

Apache Cassandra: описание директорий, язык CQL, утилита cqlsh

Прежде, чем продолжать знакомство с Apache Cassandra — давайте посмотрим — какие каталоги и файлы идут «в комплекте».

Со страницы загрузок выбираем зеркало и загружаем файл:

Структура каталогов Apache Cassadnra выглядит так:

При установке скомпилированной версии — перед запуском создайте и установите владельца для каталогов:

Замените setevoy на пользователя, от имени которого будет запускаться Cassandra.

Теперь можно запускать сервер:

Cassandra CLI и cqlsh

Для управления сервером и нодами можно использовать имеющуюся утилиту командной строки cassandra-cli (которая использует упомянутый выше Thrift-сервер):

Но она уже считается устаревшей:

И поэтому используем утилиту cqlsh :

Cassandra используется язык запросов CQL (Cassandra Query Language).

Подсказка по командам

Для получения подсказки по конкретной команде:

После установки Cassandra имеет только два пространства ключей (keyspace), которые можно посмотреть так:

Они являются аналогами баз mysql и performance_shema в MySQL и не предназначены для работы пользователя.

Получить информацию по самому кластеру, к которому вы подключены, можно так:

Больше про команду DESCRIBE можно почитать тут>>>,

Пространство ключей (keyspace) — что-то схожее с базой данных в реляционных базах данных, которая содержит описание одной или нескольких семейств колонок (column family), которые, грубо говоря, являются аналогами таблиц в базах типа MySQL.

Для создания нового keyspace — используется команда CREATE KEYSPACE:

Классы репликации мы рассмотрим позже.

Переключаемся на работу с новым keyspace :

Если выполнить DESCRIBE KEYSPACES (можно сократить до DESC KEYSPACES ) — среди системных баз появится и наша:

Для получения более полной информации — укажите имя keyspace :

Для создания таблицы (column family) в новой базе — используется команда CREATE TABLE :

Если вызвать desc keyspace testkeyspace ещё раз — мы увидим новую таблицу:

А что бы удалить всю таблицу — DROP TABLE :

Создадим новую таблицу:

Добавление данных выполняется помощью INSERT :

Или с помощью WHERE :

Использование поля, не являющего первичным ключом, вызовет ошибку:

Источник

Как устроена apache cassandra

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra
В этом топике я хотел бы рассказать о том, как устроена кассандра (cassandra) — децентрализованная, отказоустойчивая и надёжная база данных “ключ-значение”. Хранилище само позаботится о проблемах наличия единой точки отказа (single point of failure), отказа серверов и о распределении данных между узлами кластера (cluster node). При чем, как в случае размещения серверов в одном центре обработки данных (data center), так и в конфигурации со многими центрами обработки данных, разделенных расстояниями и, соответственно, сетевыми задержками. Под надёжностью понимается итоговая согласованность (eventual consistency) данных с возможностью установки уровня согласования данных (tune consistency) каждого запроса.

NoSQL базы данных требуют в целом большего понимания их внутреннего устройства чем SQL. Эта статья будет описывать базовое строение, а в следующих статьях можно будет рассмотреть: CQL и интерфейс программирования; техники проектирования и оптимизации; особенности кластеров размещённых в многих центрах обработки данных.

Модель данных

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

С каждым значением связана метка времени — задаваемое пользователем число, которое используется для разрешения конфликтов во время записи: чем больше число, тем колонка считается новее, а при сравнении перетирает старые колонки.

По типам данных: пространство ключей и колоночное семейство — это строки (имена); метка времени — это 64-битное число; а ключ, имя колонки и значение колонки — это массив байтов. Также кассандра имеет понятие типов данных (data type). Эти типы могут по желанию разработчика (опционально) задаваться при создании колоночного семейства. Для имён колонок это называется сравнителем (comparator), для значений и ключей — валидатором (validator). Первый определяет какие байтовые значения допустимы для имён колонок и как их упорядочить. Второй — какие байтовые значение допустимы для значений колонок и ключей. Если эти типы данных не заданы, то кассандра хранит значения и сравнивает их как байтовые строки (BytesType) так как, по сути, они сохраняются внутри.

В кассандре все операции записи данных это всегда операции перезаписи, то есть, если в колоночную семью приходит колонка с таким же ключом и именем, которые уже существуют, и метка времени больше, чем та которая сохранена, то значение перезаписывается. Записанные значения никогда не меняются, просто приходят более новые колонки с новыми значениями.

Запись в кассандру работает с большей скоростью, чем чтение. Это меняет подход, который применяется при проектировании. Если рассматривать кассандру с точки зрения проектирования модели данных, то проще представить колоночное семейство не как таблицу, а как материализованное представление (materialized view) — структуру, которая представляет данные некоторого сложного запроса, но хранит их на диске. Вместо того, чтобы пытаться как-либо скомпоновать данные при помощи запросов, лучше постараться сохранить в коночное семейство все, что может понадобиться для этого запроса. То есть, подходить необходимо не со стороны отношений между сущностями или связями между объектами, а со стороны запросов: какие поля требуются выбрать; в каком порядке должны идти записи; какие данные, связанные с основными, должны запрашиваться совместно — всё это должно уже быть сохранено в колоночное семейство. Количество колонок в записи ограничено теоретически 2 миллиардами. Это краткое отступление, а подробней — в статье о техниках проектирования и оптимизации. А теперь давайте углубимся в процесс сохранения данных в кассандру и их чтения.

Распределение данных

Рассмотрим каким образом данные распределяются в зависимости от ключа по узлам кластера (cluster nodes). Кассандра позволяет задавать стратегию распределения данных. Первая такая стратегия распределяет данные в зависимости от md5 значения ключа — случайный разметчик (random partitioner). Вторая учитывает само битовое представление ключа — порядковый разметчик (byte-ordered partitioner). Первая стратегия, в большинстве своем, даёт больше преимуществ, так как вам не нужно заботиться о равномерном распределение данных между серверами и подобных проблемах. Вторую стратегию используют в редких случаях, например если необходимы интервальные запросы (range scan). Важно заметить, что выбор этой стратегии производится перед созданием кластера и фактически не может быть изменён без полной перезагрузки данных.

Для распределения данных кассандра использует технику, известную как согласованное хеширование (consistent hashing). Этот подход позволяет распределить данные между узлами и сделать так, что при добавлении и удалении нового узла количество пересылаемых данных было небольшим. Для этого каждому узлу ставится в соответствие метка (token), которая разбивает на части множество всех md5 значений ключей. Так как в большинстве случаев используется RandomPartitioner, рассмотрим его. Как я уже говорил, RandomPartitioner вычисляет 128-битный md5 для каждого ключа. Для определения в каких узлах будут храниться данные, просто перебираются все метки узлов от меньшего к большему, и, когда значение метки становится больше, чем значение md5 ключа, то этот узел вместе с некоторым количеством последующих узлов (в порядке меток) выбирается для сохранения. Общее число выбранных узлов должно быть равным уровню репликации (replication factor). Уровень репликации задаётся для каждого пространства ключей и позволяет регулировать избыточность данных (data redundancy).

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

Перед тем, как добавить узел в кластер, необходимо задать ему метку. От того, какой процент ключей покрывает промежуток между этой меткой и следующей, зависит сколько данных будет храниться на узле. Весь набор меток для кластера называется кольцом (ring).

Вот иллюстрация отображающая при помощи встроенной утилиты nodetool кольцо кластера из 6 узлов с равномерно распределенными метками.

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

Согласованность данных

Узлы кластера кассандры равноценны, и клиенты могут соединятся с любым из них, как для записи, так и для чтения. Запросы проходят стадию координации, во время которой, выяснив при помощи ключа и разметчика на каких узлах должны располагаться данные, сервер посылает запросы к этим узлам. Будем называть узел, который выполняет координацию — координатором (coordinator), а узлы, которые выбраны для сохранения записи с данным ключом — узлами-реплик (replica nodes). Физически координатором может быть один из узлов-реплик — это зависит только от ключа, разметчика и меток.

Для каждого запроса, как на чтение, так и на запись, есть возможность задать уровень согласованности данных.

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

Таким образом, можно регулировать временные задержки операций чтения, записи и настраивать согласованность (tune consistency), а также доступность (availability) каждой из видов операций. По сути, доступность напрямую зависит от уровня согласованности операций чтения и записи, так как он определяет, сколько узлов-реплик может выйти из строя, и при этом эти операции все ещё будут подтверждены.

Если число узлов, с которых приходит подтверждения о записи, в сумме с числом узлов, с которых происходит чтение, больше, чем уровень репликации, то у нас есть гарантия, что после записи новое значение всегда будет прочитано, и это называется строгой согласованностью (strong consistency). При отсутствии строгой согласованности существует возможность того, что операция чтения возвратит устаревшие данные.

В любом случае, значение в конце концов распространится между репликами, но уже после того, как закончится координационное ожидание. Такое распространение называется итоговой согласованностью (eventual consistency). Если не все узлы-реплики будут доступны во время записи, то рано или поздно будут задействованы средства восстановления, такие как чтение с исправлением и анти-энтропийное восстановление узла (anti-entropy node repair). Об этом чуть позже.

Таким образом, при уровне согласованности QUORUM на чтение и на запись всегда будет поддерживаться строгая согласованность, и это будет некий баланс между задержкой операции чтения и записи. При записи ALL, а чтении ONE будет строгая согласованность, и операции чтения будут выполняться быстрее и будут иметь большую доступность, то есть количество вышедших из строя узлов, при котором чтение все еще будет выполнено, может быть большим, чем при QUORUM. Для операций записи же потребуются все рабочие узлы-реплик. При записи ONE, чтении ALL тоже будет строгая согласованность, и операции записи будут выполняться быстрее и доступность записи будет большой, ведь будет достаточно подтвердить лишь, что операция записи прошла хотя бы на одном из серверов, а чтение — медленней и требовать всех узлов-реплик. Если же к приложению нету требования о строгой согласованности, то появляется возможность ускорить и операции чтения и операции записи, а также улучшить доступность за счет выставления меньших уровней согласованности.

Восстановление данных

Запись на диск

Когда данные приходят после координации на узел непосредственно для записи, то они попадают в две структуры данных: в таблицу в памяти (memtable) и в журнал закрепления (commit log). Таблица в памяти существует для каждого колоночного семейства и позволяет запомнить значение моментально. Технически это хеш-таблица (hashmap) с возможностью одновременного доступа (concurrent access) на основе структуры данных, называемой “списками с пропусками” (skip list). Журнал закрепления один на всё пространство ключей и сохраняется на диске. Журнал представляет собой последовательность операций модификации. Так же он разбивается на части при достижении определённого размера.

Такая организация позволяет сделать скорость записи ограниченной скоростью последовательной записи на жесткий диск и при этом гарантировать долговечность данных (data durability). Журнал закрепления в случае аварийного останова узла читается при старте сервиса кассандры и восстанавливает все таблицы в памяти. Получается, что скорость упирается во время последовательной записи на диск, а у современных жёстких дисков это порядка 100МБ/с. По этой причине журнал закрепления советуют вынести на отдельный дисковый носитель.

Понятно, что рано или поздно память может заполниться. Поэтому таблицу в памяти также необходимо сохранить на диск. Для определения момента сохранения существует ограничение объёма занимаемыми таблицами в памяти (memtable_total_spacein_mb), по умолчанию это ⅓ максимального размера кучи Java (Java heapspace). При заполнении таблицами в памяти объёма больше чем это ограничение, кассандра создает новую таблицу и записывает старую таблицу в памяти на диск в виде сохраненной таблицы (SSTable). Сохранённая таблица после создания больше никогда не модифицируется (is immutable). Когда происходит сохранение на диск, то части журнала закрепления помечаются как свободные, таким образом освобождая занятое журналом место на диске. Нужно учесть, что журнал имеет переплетённую структуру из данных разных колоночных семейств в пространстве ключей, и какие-то части могут быть не освобождены, так как некоторым областям будут соответствовать другие данные, все ещё находящиеся в таблицах в памяти.

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

Уплотнение

В определенный момент времени данные в колоночном семействе перезапишутся — придут колонки, которые будут иметь те же имя и ключ. То есть, возникнет ситуация, когда в более старой сохранённой таблице и более новой будут содержаться старые и новые данные. Для того, чтобы гарантировать целостность, кассандра обязана читать все эти сохранённые таблицы и выбирать данные с последней меткой времени. Получается, что количество операций позиционирования жёсткого диска при чтении пропорционально количеству сохранённых таблиц. Поэтому для того, чтобы освободить перезаписанные данные и уменьшить количество сохранённых таблиц, существует процесс уплотнения (compaction). Он читает последовательно несколько сохранённых таблиц и записывает новую сохранённую таблицу, в которой объединены данные по меткам времени. Когда таблица полностью записана и введена в использование, кассандра может освободить таблицы-источники(таблицами, которые её образовали). Таким образом, если таблицы содержали перезаписанные данные, то эта избыточность устраняется. Понятно, что во время такой операции объем избыточности увеличивается — новая сохранённая таблица существует на диске вместе с таблицами-источниками, а это значит, что объем места на диске всегда должен быть такой, чтобы можно было произвести уплотнение.

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

Операции удаления

С точки зрения внутреннего устройства, операции удаление колонок — это операции записи специального значения — затирающего значения (tombstone). Когда такое значение получается в результате чтения, то оно пропускается, словно такого значения никогда и не существовало. В результате же уплотнения, такие значения постепенно вытесняют устаревшие реальные значения и, возможно, исчезают вовсе. Если же появятся колонки с реальными данными с еще более новыми метками времени, то они перетрут, в конце концов, и эти затирающие значения.

Транзакционность

Послесловие

Итак, мы рассмотрели как устроены основные операции — чтение и запись значений в кассандру.

Просьба: замечания по орфографии и идеи по улучшению статьи высказывайте в личном сообщении.

Источник

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

Статья предназначена для людей пытающихся создать свою первую «таблицу» в БД Cassandra.

Disclaimer

Ликбез

Основное правило моделирования данных в C*

Первый пример.

У нас есть сотрудники какой-то компании. Создадим таблицу (которые на самом деле называются Column Family, но для простоты перехода с SQL на CQL используют слово table) на CQL и заполним данными:

Таблицы в C* обязаны иметь PRIMARY KEY. Он используется для поиска ноды, в которой хранится искомая строка.

Эта картинка — руками разукрашенный вывод cqlsh.
Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

Выглядит как обычная таблица из реляционной БД. C* создаст две строки.
Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra
Внимание! Это две внутренние структуры строк, а не таблицы. Если чуть слукавить, то можно сказать, что каждая строка — это как маленькая таблица. Далее понятней.

Второй пример.

Усложняем. Добавим название компании.

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra
Внимание на PRIMARY KEY. Первый из параметров — company — это распределительный ключ, именно он будет использоваться для поиска ноды с этих пор. Второй ключ name — это кластерный ключ (clustering key). Он превращается в колонку. Т.е. мы данные превращаем в название колонки. Был ‘eric’ обычными четырмя байтами, а стал частью названия колонки.

Третий пример.

Ещё сложнее. Заглавная буква — название колонки. Строчная — данные.

Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

Внутрення структура усложнилась. Такие данные как c, d, g, k, o, p, u, v участвуют в названии колонок наравне с E и F:
Язык запросов в cassandra. Смотреть фото Язык запросов в cassandra. Смотреть картинку Язык запросов в cassandra. Картинка про Язык запросов в cassandra. Фото Язык запросов в cassandra

Почему так сложно?

Это самый быстрый способ записи и хранения бесконечного количества данных в распределённой БД. C* как раз была разработана с упором на скорость записи/чтения. Вот, например, сравнение скоростей MongoDB, HBase и С*.

Пример из реальной жизни

Первый и второй пункты — легко.

Нам нужно установить несколько нод, сделать каждую автономной. Может даже вынести одну из них в облако.

Третий пункт — основная хитрость.

Мы будем хранить данные одного дня в одной строке.

Так как распределительным ключом является уникальная комбинация день+датчик, то данные за один день будут храниться для каждого датчика в отдельной строке. Благодаря обратной сортировке внутри строки мы получаем самые важные для нас данные (последние) «на кончике пальцев».
Так как поиск распределительного ключа (дня) — очень быстрая операция в С*, то третий пункт можно считать выполненным.

Четвертый пункт

Конечно, мы можем сделать поиск дня/дней, а внутри дня уже сравнивать timestamp. Но дней может быть очень много.
У нас ведь всего 10 датчиков. Нельзя ли этим воспользоваться? Можно, если представить, что один датчик — одна строка. В этом случае С* закеширует в памяти местоположение всех десяти строк на диске.

Создадим вторую таблицу, где будем хранить те же самые данные, но без учета дней.

И когда будем вставляеть данные, то ограничим время жизни каждой ячейки чтобы не привысить 2 млрд колонок. У нас каждый датчик даёт не более 100 показаний в секунду. Отсюда:
2**31 / (24 часа * 60 мин * 60 сек * 100 событий/сек) = 2147483648 / (24 * 60 * 60 * 100) = 248.55 дней
Надо сделать, чтобы через 248 дней самые старые данные тихо и незаметно самоудалялись.

Источники

UPD: Исправление терминологии. Заменил слова «главный ключ» на «распределительный ключ» в нужных местах. Добавил кое-где понятие «кластерный ключ».

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *