Cassandra что это
Перейти к содержимому

Cassandra что это

  • автор:

Что такое Cassandra

Обновлено

Обновлено: 23.12.2022 Опубликовано: 27.12.2020

колоночная распределенная система управления базами данных (РСУБД) класса NoSQL (Not Only SQL). Рассчитана на работу с большими массивами информации. Написана в Facebook на Java и передана в 2009 году в фонд Apache Software Foundation.

Поддерживаются системы Linux на основе пакетов deb (Debian, Ubuntu) и RPM (Red Hat, CentOS). Для работы Cassandra требуется Java. Сама СУБД устанавливается из репозитория или бинарника, а также, как процесс docker. Скачать последнюю версию можно с официального сайта. На нем же можно ознакомиться с документацией (но только на английском языке).

Cassandra поддерживает свой собственный язык запросов — CQL. Он схож с SQL, но поддерживает только простейшие запросы SELECT. Также в ней нет команды INSERT — вместо нее и для добавления, и для обновления используется UPDATE. Подключение к базе можно выполнить с помощью cqlsh — оболочки, которая идет в комплекте с Cassandra.

  • Нет транзакций.
  • Нет поддержки JOIN в запросах.
  • Нет поддержки логического оператора ИЛИ (OR) в WHERE.
  • При создании вторичного индекса создается новая таблица.
  • При удалении записей, они еще какое-то время остаются в системе.
  • Идемпотентные операции — повторное действие оставляется систему в таком же состоянии.

Cassandra устанавливается в режиме кластера. Узел, на который отправляется запрос считается координатором. Он автоматически отправляет изменения на часть нод кластера (согласно настройки Replication Factor), которые будут называться репликами. Также при попытке сделать выборку, координатор может разбить запрос по разным нодам.

  1. Высокая скорость работы.
  2. Отказоустойчивость и масштабирование.
  1. Плохо подходит для проектов, где часто меняются или удаляются данные.
  2. Нет транзакций.

Среди других баз класса NoSQL можно выделить:

Подробнее о Cassandra на Википедии.

В чем разница между Cassandra и MongoDB?

Apache Cassandra и MongoDB – это две базы данных NoSQL, в которых данные хранятся в нетабличном формате. Cassandra – это ранняя база данных NoSQL с гибридным дизайном табличного хранилища и хранилища ключей и значений. Она предназначена для хранения данных для приложений, требующих высокой производительности чтения и записи. В отличие от нее, MongoDB – база данных документов, созданная для общего использования. Она имеет гибкую модель данных, которая позволяет хранить неструктурированные данные в оптимизированном формате JSON, называемом Binary JSON, или BSON. База данных MongoDB обеспечивает полную поддержку индексирования и репликации с помощью богатых и интуитивно понятных API.

В чем сходство Cassandra и MongoDB?

И Apache Cassandra, и MongoDB принадлежат к группе баз данных NoSQL. Базы данных NoSQL могут хранить структурированные, неструктурированные и полуструктурированные данные без схемы базы данных.

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

Кроме того, Cassandra и ранние версии MongoDB имеют открытый исходный код. Это означает, что вы можете загрузить исходный код этих баз данных NoSQL и настроить их по своему усмотрению.

Команда Facebook разработала сервис Cassandra, а затем выпустила его как проект с открытым исходным кодом с Apache. MongoDB был разработан небольшой группой разработчиков под руководством MongoDB, Inc. Все версии MongoDB, выпущенные до 16 октября 2018 г., доступны под лицензией GNU Affero General Public License.

Различия в моделях данных: Cassandra и MongoDB

Хотя MongoDB и Apache Cassandra являются базами данных NoSQL, они по-разному хранят данные и управляют ими.

Cassandra

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

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

Структуру таблицы Apache Cassandra можно визуализировать в следующем примере.

Значение – Джон Доу

Значение – Соединенные Штаты

Столбец – электронная почта

Значение – Джейн Доу

MongoDB

Напротив, MongoDB хранит данные без схемы, используя оптимизированный формат Binary JSON (BSON). Сервис может хранить несколько типов данных в одном документе, аналогично объектам JSON, а затем сериализовать их с помощью BSON.

MongoDB организует документы в наборы, которые могут содержать данные с различными структурами. Такая модель данных гибкая и может обрабатывать большие объемы неструктурированных данных.

Ниже приведен пример данных клиентов в MongoDB.

country: «United States»

Архитектурные различия: Cassandra и MongoDB

Из-за различий в моделях данных Cassandra и MongoDB по-разному реализуют несколько функций баз данных.

Базовая единица хранения

В Cassandra таблицы отсортированных строк (SSTable) являются основной единицей хранения данных, используемой для хранения данных на диске. SSTable – это файл, содержащий отсортированный набор пар «ключ-значение» для определенного семейства столбцов (таблицы) и раздела. Таблицы SSTable неизменяемы, а это значит, что после записи их нельзя изменить.

В MongoDB основной единицей хранения является документ. Документ – это набор пар «ключ-значение», где ключи представляют собой строки, а значения могут быть разных типов. Например, значениями могут быть другие документы, массивы, строки, числа, даты и логические значения. Документы хранятся в наборах.

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

Язык запросов – это операторы, которые вы используете для вставки и извлечения данных из базы данных.

Язык запросов Cassandra (CQL) – это язык запросов, который вы используете в Cassandra. Хотя его синтаксис и структура аналогичны SQL, Apache разработал CQL для работы с моделью данных семейства столбцов.

С другой стороны, MongoDB использует язык запросов MongoDB (MQL), который содержит команды, аналогичные Node.js. MQL поддерживает операции создания, чтения, обновления и удаления (CRUD). Команды MQL можно писать в оболочке MongoDB.

Индексирование

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

Cassandra поддерживает два типа индексов:

  • Вторичные индексы в отдельных столбцах
  • Вторичные индексы SSTable-Attached (SASI) на нескольких столбцах

Индексы SASI хранят данные индекса непосредственно в таблицах SSTable. Они поддерживают сложные запросы, такие как диапазон, префикс и полнотекстовый поиск по столбцам с большим количеством уникальных значений.

Напротив, MongoDB поддерживает индексацию на уровне набора и на уровне поля. Таким образом предоставляется несколько типов индексов, таких как индексы с одним полем, составные индексы и индексы с множественными ключами. Также предлагаются следующие индексы:

  • специализированный геопространственный индекс для географически распределенных данных
  • индекс текстового поиска для больших объемов текстовых данных
  • хэшированные и кластеризованные индексы для числовых данных

Параллельные операции

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

Cassandra обеспечивает параллельную роботу за счет согласованности проигрывателей и атомарности на уровне строк. Только один пользователь может работать с одной строкой одновременно.

При согласованности проигрывателя каждый узел-реплика поддерживает векторные часы, представляющие собой структуру данных, которая отслеживает историю версий связанных данных. При выполнении операции записи векторные часы обновляются в соответствии с новой версией. Когда выполняется операция чтения, Cassandra возвращает версию с наибольшей временной меткой во всех репликах, благодаря чему всегда возвращается самая последняя версия данных.

Напротив, MongoDB поддерживает механизмы управления параллелизмом нескольких версий (MVCC). MVCC позволяет одновременно поддерживать несколько версий одного и того же документа данных. Каждый документ имеет уникальный идентификатор версии, который повышается при каждом обновлении. Блокирование на уровне документов и MVCC обеспечивают более надежную стратегию параллелизма.

Доступность

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

В Apache Cassandra каждый узел кластера содержит реплики данных для других узлов. Координаты каждого узла считываются на нужный узел для записи или извлечения данных. Одновременно также восстанавливаются данные, которые не согласованы между узлами. Это может повлиять на производительность в любом масштабе.

Напротив, MongoDB использует репликацию на одном первичном узле для обеспечения высокой доступности данных. MongoDB реплицирует данные в наборы реплик. Только один первичный узел получает записи, а другие просто реплицируют данные с первичного узла. Однако первичный узел создает единую точку отказа.

Масштабируемость

И Cassandra, и MongoDB поддерживают сегментирование – метод горизонтального разделения данных между несколькими узлами кластера. Например, если у вас тысячи клиентов, вы разделяете данные так, чтобы на каждом узле была информация только о нескольких сотнях клиентов. Таким образом вы сможете масштабировать базу данных, не создавая ограничений пропускной способности.

Cassandra использует алгоритм распределенного хэширования, называемый последовательным хэшированием, чтобы определить, какой узел отвечает за определенное значение данных. Cassandra также поддерживает виртуальные узлы (vnodes), которые позволяют одному физическому узлу иметь несколько диапазонов данных.

Напротив, MongoDB использует ключи сегментирования, чтобы определить, куда может попасть значение данных. Администраторы баз данных могут определить ключи сегментирования для распределения данных на разделы. Данные можно разделить на основе таких факторов, как географическое положение, алфавитный порядок или любая другая система, наиболее эффективная для вашего набора данных.

Когда использовать Cassandra, а когда – MongoDB

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

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

Формат данных

Apache Cassandra имеет более структурированную систему хранения данных, чем MongoDB. Если данные, с которыми вы работаете, имеют фиксированный формат, лучше подойдет Cassandra.

Если данные более динамичны и не имеют согласованной структуры, MongoDB будет более подходящим.

Доступность

В MongoDB есть первичный узел, а затем серия реплик. Если основной узел выходит из строя, MongoDB тратит несколько минут на выбор узла-реплики для замены. Это может привести к небольшому времени простоя.

Cassandra использует систему распределенных узлов с большим количеством главных узлов, что обеспечивает 100 % бесперебойную работу.

Масштабируемость

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

Производительность Cassandra может немного снизиться в зависимости от значений данных.

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

И язык запросов Cassandra (CQL), и язык запросов MongoDB (MQL) являются высокоэффективными языками запросов. Однако CQL гораздо больше похож на SQL, поэтому вы можете легко использовать CQL, если уже знакомы с SQL.

У MQL есть различные реализации и синтаксис, поэтому его изучение может оказаться более сложным.

Поддержка языков программирования

MongoDB поддерживает двенадцать языков программирования: C, C++, C#, Go, Java, Node.js, PHP, Python, Ruby, Rust, Scala и Swift.

Cassandra поддерживает меньшее количество языков, таких как Java, JavaScript, Perl, Ruby, Scala, C#, Erlang, PHP, Python и т. д.

Как устроена apache 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).

  • пространством ключей — это привязка к приложению (предметной области). Позволяет на одном кластере размещать данные разных приложений;
  • колоночным семейством — это привязка к запросу;
  • ключом — это привязка к узлу кластера. От ключа зависит на какие узлы попадут сохранённые колонки;
  • именем колонки — это привязка к атрибуту в записи. Позволяет в одной записи хранить несколько значений.

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

По типам данных: пространство ключей и колоночное семейство — это строки (имена); метка времени — это 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 миллиардами. Это краткое отступление, а подробней — в статье о техниках проектирования и оптимизации. А теперь давайте углубимся в процесс сохранения данных в кассандру и их чтения.

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

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

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

Репликация данных

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

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

nodetool ring

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

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

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

Запись в кассандру

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

  • ONE — координатор шлёт запросы всем узлам-реплик, но, дождавшись подтверждения от первого же узла, возвращает управление пользователю;
  • TWO — то же самое, но координатор дожидается подтверждения от двух первых узлов, прежде чем вернуть управление;
  • THREE — аналогично, но координатор ждет подтверждения от трех первых узлов, прежде чем вернуть управление;
  • QUORUM — собирается кворум: координатор дожидается подтверждения записи от более чем половины узлов-реплик, а именно round(N / 2) + 1, где N — уровень репликации;
  • LOCAL_QUORUM — координатор дожидается подтверждения от более чем половины узлов-реплик в том же центре обработки данных, где расположен координатор (для каждого запроса потенциально свой). Позволяет избавиться от задержек, связанных с пересылкой данных в другие центры обработки данных. Вопросы работы с многими центрами обработки данных рассматриваются в этой статье вскользь;
  • EACH_QUORUM — кооринатор дожидается подтверждения от более чем половины узлов-реплик в каждом центре обработки данных независимо;
  • ALL — координатор дожидается подтверждения от всех узлов-реплик;
  • ANY — даёт возможность записать данные, даже если все узлы-реплики не отвечают. Координатор дожидается или первого ответа от одного из узлов-реплик, или когда данные сохранятся при помощи направленной отправки (hinted handoff) на координаторе.

  • ONE — координатор шлёт запросы к ближайшему узлу-реплике. Остальные реплики также читаются в целях чтения с исправлением (read repair) с заданной в конфигурации кассандры вероятностью;
  • TWO — то же самое, но координатор шлёт запросы к двум ближайшим узлам. Выбирается то значение, которое имеет большую метку времени;
  • THREE — аналогично предыдущему варианту, но с тремя узлами;
  • QUORUM — собирается кворум, то есть координатор шлёт запросы к более чем половине узлов-реплик, а именно round(N / 2) + 1, где N — уровень репликации;
  • LOCAL_QUORUM — собирается кворум в том центре обработки данных, в котором происходит координация, и возвращаются данные с последней меткой времени;
  • EACH_QUORUM — координатор возвращает данные после собрания кворума в каждом из центров обработки данных;
  • ALL — координатор возвращает данные после прочтения со всех узлов-реплик.

Чтение из кассандры

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

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

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

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

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

  • чтение с восстановлением (read repair) — во время чтения данные запрашиваются со всех реплик и сравниваются уже после завершения координации. Та колонка, которая имеет последнюю метку времени, распространится на узлы, где метки устаревшие.
  • направленной отправки (hinted handoff) — позволяет сохранить информацию об операции записи на координаторе в том случае, если запись на какой-либо из узлов не удалась. Позже, когда это будет возможно, запись повторится. Позволяет быстро производить восстановление данных в случае краткосрочного отсутствия узла в кластере. Кроме того, при уровне согласованности ANY позволяет добиться полной доступности для записи (absolute write availability), когда даже все узлы-реплик недоступны, операция записи подтверждается, а данные сохранятся на узле-координаторе.
  • анти-энтропийное восстановление узла (anti-entropy node repair) — это некий процесс восстановления всех реплик, который должен запускаться регулярно вручную при помощи команды “nodetool repair” и позволяет поддержать количество реплик всех данных, которые возможно были не восстановлены первыми двумя способами, на требуемом уровне репликации.

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

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

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

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

Сохранение значения на диск

  • блум-фильтр — это структура данных, которая занимает немного места и позволяет ответить на вопрос: содержится ли элемент, а в нашем случае это ключ, в множестве или нет. При чем, если ответ — “нет”, то это 100%, а если ответ “да”, то это, возможно, ложно-положительный ответ. Это позволяет уменьшить количество чтений из сохранённых таблиц;
  • кэш ключей сохраняет позицию на диске записи для каждого ключа, таким образом уменьшая количество операций позиционирования (seek operations) во время поиска по сохранённой таблице;
  • кэш записей сохраняет запись целиком, позволяя совсем избавиться от операций чтения с диска.

Чтения с диска

Уплотнение

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

Уплотнение

  • стратегия уплотнения сохраненных таблиц связанных размером (size-tiered compaction) — эта стратегия уплотняет определенным образом выбранные две таблицы. Применяется автоматически в виде фонового уплотнения (minor compaction) и в ручном режиме, для полного уплотнения (major compaction). Допускает ситуацию нахождения ключа во многих таблицах и, соответственно, требует выполнять операцию поиска для каждой такой таблицы.
  • стратегия уплотнение сохраненных таблиц уровнями (leveled compaction) — уплотняет сохраненные таблицы, которые изначально создаются небольшими — 5 МБ, группируя их в уровни. Каждый уровень в 10 раз больший чем предыдущий. Причем, существуют такие гарантии: 90% запросов чтения будут происходить к одной сохраненной таблице, и только 10% пространства на диске будет использоваться под устаревшие данные. В этом случае для выполнения уплотнения под временную таблицу достаточно только 10-кратного размера таблицы, то есть 50 Мб. Подробнее в этой статье

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

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

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

  • атомарность (atomicity) — все колонки в одной записи за одну операцию будут или записаны, или нет;
  • согласованность (consistency) — как уже было сказано выше, есть возможность использовать запросы с строгой согласованностью взамен доступности, и тем самым выполнить это требование;
  • изолированность (isolation) — начиная с кассандры версии 1.1, появилась поддержка изолированности, когда во время записи колонок одной записи другой пользователь, который читает эту же запись, увидит или полностью старую версию записи или, уже после окончания операции, новую версию, а не часть колонок из одной и часть из второй;
  • долговечность (durability) обеспечивается наличием журнала закрепления, который будет воспроизведён и восстановит узел до нужного состояния в случае какого-либо отказа.

Послесловие

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

  • Страница на apache.org cassandra.apache.org
  • Документация на datastax.com www.datastax.com/docs/1.1/index#apache-cassandra-1-1-documentation
  • Про BigTable research.google.com/archive/bigtable.html
  • Про Amazon Dynamo www.allthingsdistributed.com/2007/10/amazons_dynamo.html
  • Просто один из блогов, про модель данных maxgrinev.com/2010/07/09/a-quick-introduction-to-the-cassandra-data-model

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

  • apache cassandra
  • cassandra
  • nosql
  • очень много букв
  • статья для прямой записи в подкорку

Cassandra что это

Хранилище Cassandra предназначено для обработки нагрузки данных больших объемов между множеством узлов без отказа системы. Его архитектура основана на том, что сбои в системе и аппаратных средствах возможны, и они происходят. Данное хранилище решает проблему сбоев, используя одноранговую (децентрализованную) распределенную систему между однородными узлами, где данные распределены между всеми узлами кластера. Все узлы обмениваются информацией по кластеру каждую секунду. Последовательно записанные логи изменений в каждом узле фиксируют активность записи для обеспечения долговечности данных. Далее данные индексируются и записываются в элемент памяти, который называется Memtable , очень похожий на кэш обратной записи. Когда этот элемент памяти полон, данные записываются на диск в файл данных SSTable . Все записи автоматически разделяются и копируются по всему кластеру. Во время процесса, который назвается уплотнение ( compaction ), хранилище периодически объединяет файлы SSTable , отбрасывая устаревшую информацию и индикаторы об удалении данных.

Cassandra — это строчно-ориентированная база данных. Ее архитектура позволяет каждому авторизованному пользователю подключаться к произвольному узлу любого дата-центра и получать доступ к данным, используя язык CQL. Для простоты использования язык CQL имеет синтаксис аналогичный языку SQL. С точки зрения языка CQL база данных состоит из таблиц. Обычно кластер имеет одно пространство ключей ( keyspace ) для каждого приложения. Разработчики могут получить доступ к CQL через cqlsh , а также с помощью драйверов для языков приложений.

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

Основные компоненты
  • Узел (Node) — место хранения данных. Это основной элемент хранилища Cassandra.
  • Дата-центр (Data center) — набор связанных между собой узлов. Он может быть физическим либо виртуальным центром. Разные рабочие нагрузки должны использовать отдельные дата-центры (физические либо виртуальные вне зависимости от типа). Репликация устанавливается дата-центром. Использование отдельных центров предотвращает влияние других нагрузок на транзакции хранилища и позволяет хранить запросы рядом для уменьшения задержки времени. В зависимости от коэффициента репликации данные могут быть синхронизированы в множестве дата-центрах. В любом случае, дата-центры никогда не занимают физическое местоположение.
  • Кластер (Cluster) . Кластер состоит из одного или нескольких дата-центров. Он может иметь некое физическое местоположение.
  • Логи изменений (Commit log) . Все данные вначале записываются в логи изменений для обеспечения их долговечности. После того, как все данные будут переданы в SSTables , они могут быть заархивированы, удалены либо переработаны.
  • Таблица (Table) — набор упорядоченных столбцов, использующихся по строкам. Строка содержит столбцы и первичный ключ. Первая часть ключа это название столбца.
  • Отсортированная строковая таблица SSTable (SSTable — sorted string table) — неизменяемый файл данных, к которому хранилище периодически добавляет информацию из таблиц Memtable . В таблицу SSTable возможно только добавлять данные. Они хранятся в последовательном порядке на диске и поддерживаются для каждой таблицы хранилища Cassandra.
Основные компоненты настройки хранилища
  • Госсип (Gossip) — одноранговый протокол связи, который используется для обнаружения и передачи информации о местоположении и состоянии других узлов в кластере хранилища Cassandra. Данная информация также сохраняется локально на каждом узле для использования сразу после перезагрузки узла.
  • Партиционер (Partitioner) — определяет, какой узел получит первую копию фрагмента данных и как распределить другие копии между остальными узлами кластера. Каждая строка данных имеет уникальный идентификатор в виде первичного ключа, который может соответствовать ее ключу раздела, но при этом может содержать иные кластерные столбцы. Партиционер — это хэш-функция, которая извлекает значение маркера из первичного ключа строки. Партиционер использует значение маркера для определения того, какие узлы кластера получают копии этой строки. Партиционер Murmur3Partitioner — это стандартная стратегия разделения для новых кластеров хранилища Cassandra, а также верный вариант для новых кластеров практически во всех случаях. Для каждого узла необходимо установить партиционер и присвоить значение параметру num_tokens . Значение этого параметра зависит от аппаратных возможностей системы. Если не используются виртуальные узлы (vnodes), вместо num_tokens нужно присваивать значение параметру initial_token .
  • Коэффициент репликации (Replication factor) — общее количество копий по всему кластеру. Коэффициент репликации, равный 1, означает, что на одном узле имеется только одна копия каждой строки. Коэффициент репликации, равный 2, означает, что имеется две копии каждой строки, но эти копии находятся на разных узлах. Все копии одинаково важны, нет первичной либо главной копии. Необходимо определять коэффициент репликкации для каждого дата-центра. Как правило, желательно устанавливать значение коэффициента больше чем один, но не более чем количество узлов в кластере.
  • Стратегия размещения реплики (Replica placement strategy) . Хранилище Cassandra хранит копии данных на множестве узлов для обеспечения надежности и отказоустойчивости. Стратегия репликации определяет, на каких узлах необходимо размещать копии. Первая реплика данных это просто первая копия данных, она не уникальна. Для большинства случаев настоятельно рекомендуется использовать NetworkTopologyStrategy , потому что данная стратегия позволяет легко увеличивать количество дата-центров при необходимости дальнейшего расширения. При создании пространства ключей необходимо определить стратегию размещения реплики и необходимое количество копий.
  • Снитч (Snitch) — определяет группы машин в дата-центрах и на стойках (топологиях), которые используются стратегией репликации для размещения копий. Настраивать снитч необходимо при создании кластера. Все снитчи используют динамический слой, который контролирует производительность и выбирает лучшую копию для чтения. Он включен по умолчанию и рекомендован для использования в большинстве сборок. Граничные значения динамических снитчей настраиваются для каждого узла в конфигурационном файле cassandra.yaml . Использующийся по умолчанию SimpleSnitch не распознает дата-центры и стойки информации. Его рекомендуется использовать для развертываний с одним дата-центром или для одиночной зоны в общедоступных облаках. GossipingPropertyFileSnitch рекомендован для промышленной эксплуатации. Он определяет узел дата-центра и стойку, и использует госсипы для распространения данной информации другим узлам.
  • Файл конфигурации cassandra.yaml — основной конфигурационный файл для установки свойств инициализации кластера, кэширования параметров таблиц, свойств настройки и использования ресурсов, настроек тайм-аута, клиентских подключений, резервного копирования и безопасности. По умолчанию узел настроен для хранения данных, которыми он управляет в директории, установленной в файле cassandra.yaml ( /var/lib/cassandra при установке из пакета). В развертываниях промышленного кластера можно изменить директорию commitlog-directory на другой диск из data_file_directories .
  • Свойства таблицы системного ключевого пространства (System keyspace tableproperties) . Для установки атрибутов конфигурации хранилища на табличном уровне либо на уровне ключевого пространства программно или с использованим клиентского приложения, такого как CQL.

Настройка и запуск кластера с несколькими узлами (один дата-центр)

Описаны сведения для развертывания кластера хранилища Cassandra с одним дата-центром. Если кластер не создан, рекомендуется изучить статьи « Cassandra and DataStax Enterprise Essentials » или « 10 Minute Cassandra Walkthrough » .

Для хранилища Cassandra термин дата-центр означает группу узлов. Дата-центр , как и группа репликации , означает группу узлов, настроенных совместно для обеспечения свойства репликаци.

Перед началом работы

Каждый узел должен быть правильно настроен перед запуском кластера. Необходимо определить или выполнить следующие действия перед началом работы:

  • Хорошо понимать, как работает Cassandra. Рекомендуется изучить как минимум следующие статьи:
  • « Архитектура хранилища Cassandra » ;
  • « Понимание архитектуры » (Understanding the architecture);
  • « Репликация данных » (Data replication);
  • « Особенности стоек хранилища Cassandra » (Cassandra’s rack feature).

Определить снитч и стратегию репликации . Для промышленных развертываний рекомендуются GossipingPropertyFileSnitch и NetworkTopologyStrategy .

  • DC1, DC2;
  • 100, 200;
  • RAC1, RAC2;
  • R101, R102

Будьте внимательны при указании имени: переименование дата-центра невозможно.

В примере описана установка кластера из 6 узлов, охватывающего 2 стойки в одном дата-центре. Каждый узел настоен с использованием GossipingPropertyFileSnitch и 256 виртуальных узлов (vnodes) .

Установка чистого хранилища

Хранилище Cassandra устанавливается с помощью команды:

# aptitude install arta-synergy-jcr4c

После установки Cassandra проверить ее статус можно командой:

# service cassandra status

Обратите внимание: по умолчанию при установке хранилища Cassandra взамен Jackrabbit оно не содержит никаких данных — в том числе тех, которые ранее содержались в Jackrabbit. Миграцию данных необходимо выполнять специальным образом.

Процедура настройки
  1. Предполагается, что Cassandra устанавливается на следующие узлы:
node0 110.82.155.0 (seed1) node1 110.82.155.1 node2 110.82.155.2 node3 110.82.156.3 (seed2) node4 110.82.156.4 node5 110.82.156.5

Примечание : рекомендуется делать более одного seed узла для одного дата-центра

  • Пакетная установка:
  • остановка Cassandra:
$ sudo service cassandra stop
$ sudo rm -rf /var/lib/cassandra/data/system/*
  • остановка Cassandra:
$ ps auwx | grep cassandra $ sudo kill pid
$ sudo rm -rf /var/lib/cassandra/data/system/*

Примечание: после внесения любых изменений в файл cassandra.yaml необходимо перезапускать узел для применения этих изменений.

Параметры для установки:
num_tokens : рекомендуемое значение: 256

seeds : внутренний IP-адрес для каждого раздающего узла .
Раздающие узлы не проходят инициализацию, которая выполняется для каждого нового узла, присоединяемого к существующему кластеру. Для новых кластеров процесс инициализации для раздающих узлов пропускается.

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

endpoint_snitch : имя снитча .
Если снитчи были изменены, то рекомендуется изучить статью « Замена снитчей » (Switching snitches).

Примечание : если узлы в кластере идентичны в смысле дискового пространства, распределенных библиотек и т. д., можно использовать одинаковые копии файла cassandra.yaml для всех них.

Пример:

cluster_name: 'MyCassandraCluster' num_tokens: 256 seed_provider: - class_name: org.apache.cassandra.locator.SimpleSeedProvider parameters: - seeds: "110.82.155.0,110.82.155.3" listen_address: rpc_address: 0.0.0.0 endpoint_snitch: GossipingPropertyFileSnitch
  1. В файле cassandra-rackdc.properties для дата-центра и стоек требуется назначить имена, определенные перед началом работы. Например:
# indicate the rack and dc for this node dc=DC1 rack=RAC1
  • Пакетная установка:
$ sudo service cassandra start
$ cd install_location $ bin/cassandra

Примечание: если узел перезапустился из-за автоматического перезапуска, то сначала требуется остановить узел и очистить каталоги данных, как описано выше.

  1. Для проверки того, что цепь запущена и работает, выполните:
  • для пакетной установки:
$ nodetool status
$ cd install_location $ bin/nodetool status

Каждый узел должен быть указан в списке, и его статус должен быть UN (Up Normal): (илл. « Проверка работы кластера » ).

Рисунок 7.32. Проверка работы кластера

Проверка работы кластера

Миграция данных в хранилище Cassandra

Если хранилище Cassandra устанавливается на замену стандартному хранилищу Jackrabbit, уже содержащему данные, необходимо предварительно выполнить миграцию данных .

Synergy поддерживает два типа миграции: стандартную и кастомную.

Стандартная миграция

Стандартная миграция предназначена для миграции всех версий документов и последних версий файлов.

Стандартная миграция может быть « полной » или « ленивой » :

  • полная миграция требует выполнения на остановленном jboss, работа пользователей в Synergy в это время невозможна;
  • ленивая миграция выполняется на запущенном jboss; работа пользователей в Synergy, хоть и замедляется, но может быть в продолжена в штатном режиме.

Процедура выполнения полной миграции :

  1. остановить jboss: # /etc/init.d/arta-synergy-jboss stop
  2. установить пакет мигратора: # aptitude install arta-synergy-jcrmigrator
  3. запустить собственно миграцию: # /opt/synergy/utils/jcrmigrator/jcrmigrator migrate
  4. после завершения миграции установить основной пакет Хранилища arta-synergy-jcr4c : # aptitude install arta-synergy-jcr4c
  5. запустить jboss: # /etc/init.d/arta-synergy-jboss start

Выполнение ленивой миграции :

  1. остановить jboss: # /etc/init.d/arta-synergy-jboss stop
  2. установить пакет мигратора: # aptitude install arta-synergy-jcrmigrator
  3. запустить миграцию каркаса хранилища: # /opt/synergy/utils/jcrmigrator/jcrmigrator prepare Выполнение команды занимает примерно 1 минуту на 200 документов.
  4. запустить jboss: # /etc/init.d/arta-synergy-jboss start При старте jboss версии документов начинают в « ленивом » режиме мигрировать из одного хранилища в другое. При каждом старте jboss выполняется вычисление количества оставшихся версий документов.

Обратите внимание: до завершения миграции запуск и работа jboss будут выполняться медленнее, чем обычно.

Миграция в режиме debug

Если требуется более подробный вывод хода миграции, а именно отображение документов, которые в данный момент в обработке, можно воспользоваться следующими командами:

Миграция с их помощью будет проходить так же, как при выполнении ранее описанных команд migrate и prepare , но с большей детализацией.

Кастомная миграция

Кастомная миграция предназначена для миграции последних версий неудаленных документов реестров и личных карточек пользователей.

  1. остановить jboss: # /etc/init.d/arta-synergy-jboss stop
  2. установить пакет мигратора: # aptitude install arta-synergy-jcrmigrator
  3. запустить миграцию последних версий всех документов в системе (записей реестров, документов в журналах): # /opt/synergy/utils/jcrmigrator/jcrmigrator migrate_docs

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

Congratulations! You have fully migrated your documents storage to Cassandra.

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

Congratulations! You have fully migrated your files storage to Cassandra.

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

Congratulations! You have fully migrated your personal cards storage to Cassandra.

Congratulations! You have migrated all version of documents to Cassandra.

Пред. Наверх След.
Инструкция по настройке интеграции с SharePoint Начало Промежуточный локальный почтовый сервер

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

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