Погружение в СУБД Apache Cassandra

О плюсах и минусах этой базы данных NoSQL

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

Сринат Перера, старший архитектор ПО, WSO2 Inc

Фото Срината ПерерыСринат Перера (Srinath Perera) работает старшим архитектором программного обеспечения в компании WSO2, где вместе с техническим директором отвечает за общую архитектуру платформы WSO2. Он также является научным сотрудником Фонда программного обеспечения Шри-Ланка и преподает в качестве внештатного преподавателя на факультете информатики и вычислительной техники университета Моратува. Соучредитель проекта Apache Axis2 и участник проекта Apache Web Service с 2002 года, а также член фонда Apache Software, PMC и проекта Apache Web Service. Является коммиттером проектов с открытым кодом Apache Axis, Axis2 и Geronimo. Получил степень доктора философии и магистра вычислительной техники в университете штата Индиана в Блумингтоне, США, и степень бакалавра информатики и вычислительной техники в университете Моратува, Шри-Ланка.



19.03.2013

Введение

В своей статье по истории баз данных "What Goes Around Comes Around" ("Как аукнется, так и откликнется" ― см. раздел Ресурсы) Майкл Стоунбрейкер подробно описывает, как методы хранения данных эволюционировали с течением времени. До появления реляционной модели разработчики попробовали другие модели, такие как иерархические модели и направленный граф. Стоит отметить, что основанная на SQL реляционная модель ― которая даже сегодня является стандартом де-факто ― остается преобладающей около 30 лет. Это замечательное достижение, учитывая короткую историю и быстрые темпы развития вычислительной техники. Реляционная модель настолько хорошо укоренилась, что на протяжении многих лет выбор способа хранения данных для приложений был очевидным. Архитекторы решений неизменно выбирали реляционную базу данных.

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

Чтобы решить эту проблему, Google и Amazon предложили два альтернативных решения: Big Table и Dynamo (см. раздел Ресурсы), в которых они отказались от гарантий, предоставляемых реляционной моделью данных, ради более высокой масштабируемости. Позднее эти открытия формализовала «теорема CAP» Эрика Брюера (см. раздел Ресурсы). Она гласит, что для масштабируемых систем согласованность данных, надежность и устойчивость к разделению ― взаимоисключающие свойства, и невозможно построить систему, обладающую всеми этими свойствами. Вскоре, опираясь на ранние работы Google и Amazon, а также накопленные знания в области масштабируемых систем, разработчики предложили новый класс систем хранения данных. Их назвали системами NoSQL. Сначала это означало "do not use SQL if you want to scale" (не используйте SQL там, где требуется масштабирование), а позднее расшифровку заменили на "not only SQL" (не только SQL), подчеркивая, что помимо SQL-решений существуют и другие.

Известно множество систем NoSQL, и каждая исключает или изменяет те или иные аспекты реляционной модели. Стоит отметить, что ни одно из решений NoSQL не работает во всех сценариях. Каждое превосходит реляционные модели и масштабируется для некоторой ограниченной области применения. В моей предыдущей статье "Finding the Right Data Solution for Your Application in the Data Storage Haystack" (Поиск правильного решения для приложения хранения данных) обсуждается способ соблюдения требований, предъявляемых приложением к решению на базе NoSQL (см. раздел Ресурсы).

Apache Cassandra (см. раздел Ресурсы) ― одно из первых и наиболее широко используемых NoSQL-решений. Эта статья посвящена ее детальному обзору и фактам, не столь очевидным при первом знакомстве с Cassandra.


Apache Cassandra

Cassandra ― это реализация семейства NoSQL Column, поддерживающая модель данных Big Table (большая таблица) с использованием некоторых архитектурных аспектов системы Amazon Dynamo. Некоторые из преимуществ Cassandra:

  • высокая масштабируемость и надежность без элементов, отказ которых приводит к выходу из строя всей системы;
  • реализация семейства NoSQL Column;
  • очень высокая пропускная способность для операций записи и хорошая пропускная способность для операций считывания;
  • SQL-подобный язык запросов (начиная с версии 0.8) и поддержка поиска посредством вторичных индексов;
  • настраиваемая согласованность и поддержка репликации;
  • гибкая схема.

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

Cassandra хранит данные в соответствии с моделью данных "семейство столбцов", как показано на рисунке 1.

Рисунок 1. Модель данных Cassandra
Модель данных Cassandra

Что такое "столбец"?

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

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

  • Столбец ― это основной элемент модели данных Cassandra, и каждый столбец содержит имя, значение и метку времени. Мы проигнорируем метку времени, что позволит нам представить столбец как пару имя-значение (например, автор=«Азимов»).
  • Строка ― это именованная коллекция столбцов. Например, в листинге 1 показано, как могут быть представлены строки.
    Листинг 1. Пример строки
        "Second Foundation"-> {
        author="Asimov", 
        publishedDate="..",
        tag1="sci-fi", tag2="Asimov"
        }

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

  • Семейство столбцов ― это именованная коллекция строк. Листинг 2 демонстрирует, как может выглядеть пример данных.
    Листинг 2. Пример семейства столбцов
        Books->{
        "Foundation"->{author="Asimov", publishedDate=".."},
        "Second Foundation"->{author="Asimov", publishedDate=".."},
        ...
        }

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

  • Пространство ключей ― это группа из многих семейств столбцов, собранных вместе. Оно логически группирует семейства столбцов и обеспечивает изолированные области имен.

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


Модели данных Cassandra и РСУБД

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

  • Реляционные столбцы однородны по всем строкам таблицы. Обычно существует четкая вертикальная связь между элементами данных, но в случае столбцов Cassandra это не так. По этой причине вместе с каждым элементом данных (столбцом) Cassandra хранит имя столбца.
  • В реляционной модели двухмерное пространство данных является полным. В каждой точке 2D-пространства должно храниться хотя бы значение null. В случае Cassandra это тоже не так; могут быть строки, содержащие всего несколько элементов, в то время как в других их могут быть миллионы.
  • В реляционной модели схема предопределена и не может изменяться во время выполнения, в то время как Cassandra позволяет это делать.
  • Cassandra всегда хранит данные таким образом, что столбцы отсортированы по именам. Это облегчает поиск данных в столбцах с помощью секционированных запросов, но затрудняет поиск данных в строке, если не использовать распределитель, сохраняющий порядок сортировки.
  • Другим важным отличием является то, что имена столбцов в РСУБД представляют собой метаданные, а не данные. В Cassandra же имена столбцов могут включать данные. Следовательно, строки Cassandra могут иметь миллионы столбцов, тогда как в реляционной модели их обычно всего десятки.
  • Благодаря четко определенной, неизменяемой схеме реляционная модель поддерживает сложные запросы, включающие соединения, агрегирование и многое другое. В реляционной модели пользователи могут определить схему данных, не беспокоясь о запросах. Cassandra не поддерживает соединений и большинство SQL-методов поиска. Запросы, необходимые для приложения, должны быть определены в схеме.

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

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

С помощью реляционной модели такое приложение реализуется тривиально. На рисунке 2 показана схема "объекты-отношения" (Entity-Relationship - ER) для базы данных.

Рисунок 2. ER-модели для сайта оценки книг
Блок-схема модели данных сайта оценки книг

Давайте посмотрим, как это можно реализовать с помощью модели данных Cassandra. В листинге 3 показана возможная схема Cassandra, в которой первая строка представляет собой семейство столбцов Books, содержащее несколько строк, столбцы каждой из которых соответствуют свойствам книги. <TS1> и <TS2> ― метки времени.

Листинг 3. Схема Cassandra для сайта оценки книг
Books[BookID->(author, rank, price, link, tag<TS1>, tag<TS2> .., 
    cmt+<TS1>= text + "-" + author) ...
Tags2BooksIndex[TagID->(<TS1>=bookID1, <TS2>=bookID2, ..) ] 
Tags2AuthorsIndex[TagID->(<TS1>=bookID1, <TS2>=bookID2, ..) ]
RanksIndex["RANK" -> (rank<TS1>=bookID)]

Таблица 1 содержит пример набора данных согласно схеме.

Таблица 1. Пример данных для сайта оценки книг
Имя семейства столбцов Пример набора данных
Books


"Foundation" -> ("author"="Asimov", "rank"=9, "price"=14, "tag1"="sci-fi", "tag2"="future", "cmt1311031405922"="best book-sanjiva", "cmt1311031405923"="well I disagree-srinath")
"I Robot" -> ("author"="Asimov", "rank"=7, "price"=14, "tag1"="sci-fi" "tag2"="robots", "cmt1311031405924"="Asimov's best-srinath", "cmt1311031405928"="I like foundation better-sanjiva")
RanksIndex "Rank" -> (9="Foundation", 7="I Robot")
Tags2BooksIndex
"sci-fi" -> ("1311031405918"="Foundation", "1311031405919"="I Robot"
"future" -> ...
Tags2AuthorsIndex "sci-fi" -> (1311031405920="Asimov")
"future" -> ...

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

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

Приглядевшись, можно заметить, что элементы данных (комментарии и теги, которые соотносятся с книгами по принципу "один ко многим") также находятся в пределах одной строки. Для этого к именам столбцов меток и комментариев добавляется метка времени. Этот подход позволяет хранить все данные в одном столбце. Такая мера позволяет избежать операций соединения (JOIN) для извлечения данных. Так Cassandra обходит отсутствие поддержки операций соединения.

Это обеспечивает несколько преимуществ.

  • Можно получить все данные о книге за один запрос, считав целую строку.
  • Можно получить комментарии и метки без операций соединения, используя секционированные запросы с диапазонами cmt0-cmt9999 и tag0-tag9999.

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

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

Поэтому для достижения лучших результатов в модели данных Cassandra нужно выполнять поиск путем создания специальных индексов и использования порядка сортировки строк и столбцов. Другие три семейства столбцов (Tags2BooksIndex, Tags2AuthorsIndex и RankIndex) организованы именно так. Пользователям нужно искать книги по меткам, и семейство столбцов Tags2BooksIndex строит индекс, сохраняя имя метки в качестве идентификатора строки, в которую в качестве столбцов помещаются все книги, помеченные этой меткой. Как показано в примере, в качестве ключей столбца добавляются метки времени, но это для того, чтобы обеспечить уникальные идентификаторы столбцов. Реализация поиска просто считывает индекс, разыскивая строку по имени метки, и находит совпадения, считывая все столбцы, хранящиеся в строке с этим rowID.

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

Таблица 2. Сравнение реализации запросов
Описание запроса Запрос как SQL Реализация Cassandra
Список книг, отсортированных по рейтингу

Выполнение запроса
"Select * from Books order by rank" и затем для каждого результата выполнить "Select tag from Tags where bookid=?" и "Select comment from Comments where bookid=?"
Выполнить секционированный запрос к семейству столбцов RankIndex, чтобы получить упорядоченный список книг, и для каждой книги выполнить секционированный запрос к семейству столбцов Books, чтобы получить сведения о книге.
По метке найти авторов книг с данной меткой. Select distinct author from Tags, Books where Tags.bookid=Books.bookid and tag=? Считать все столбцы для данной метки из Tags2Authors с помощью секционированного запроса.
Для данной метки получить список книг с данной меткой. Select bookid from Tags where tag=? Считать все столбцы для данной метки из Tags2BooksIndex с помощью секционированного запроса.
Для данной книги получить список комментариев к этой книге, отсортированный по времени создания. Select text, time, user from Comments where bookid=? Order by time В семействе столбцов Books сделать секционированный запрос из строки, соответствующей данной книге. Они отсортированы по меткам времени, которые используются в качестве имени столбца.

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

  • Select * from Books where price > 50;
  • Select * from Books where author="Asimov"

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

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


Использование Cassandra из среды Java

У Cassandra много клиентов, написанных на разных языках. В этой статье рассматривается клиент Hector (см. раздел Ресурсы), наиболее широко используемый Java-клиент для Cassandra. Пользователи могут наращивать свои приложения, добавляя JAR-файлы Hector в classpath приложения. В листинге 4 показан пример клиента Hector.

Сначала выполняется подключение к кластеру Cassandra. Инструкции по настройке узла Cassandra содержатся на странице Cassandra Getting Started (см. раздел Ресурсы). Если конфигурация не изменена, она, как правило, работает через порт 9160. Затем определяется пространство ключей. Это можно сделать через клиент или с помощью файла конфигурации conf/cassandra.yaml.

Листинг 4. Пример кода клиента Hector для Cassandra
Cluster cluster = HFactory.createCluster('TestCluster', 
        new CassandraHostConfigurator("localhost:9160"));

//определение пространства ключей
Keyspace keyspace = HFactory.createKeyspace("BooksRating", cluster);

//добавление нового столбца. 
String rowID = "Foundation"; 
String columnFamily = "Books";

Mutator<String>
 mutator = HFactory.createMutator(keyspace, user);
mutator.insert(rowID, columnFamily, 
        HFactory.createStringColumn("author", "Asimov"));

//считывание столбца 
ColumnQuery<String, String, String>
        columnQuery = HFactory.createStringColumnQuery(keyspace);
columnQuery.setColumnFamily(columnFamily).setKey(”wso2”).setName("address");
QueryResult<HColumn<String, String>
 result = columnQuery.execute();
System.out.println("received "+ result.get().getName() + "= " 
        + result.get().getValue() + " ts = "+ result.get().getClock());

Полный код для сайта оценки книг приведен в разделе Загрузка. Он содержит примеры секционированных запросов и других сложных операций.


Архитектура Cassandra

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

Архитектура кластера Cassandra показана на рисунке 3. Сразу видно, что Cassandra ― распределенная система. Она состоит из нескольких узлов и распределяет данные между этими узлами (или секционирует их по терминологии баз данных).

Рисунок 3. Кластер Cassandra
Кластер Cassandra

Для распределения элементов данных по узлам Cassandra использует последовательное хэширование. Проще говоря, Cassandra использует хэш-алгоритм для вычисления хэш-значений ключей каждого элемента данных, хранящегося в Cassandra (имя столбца, ID строки и т.п.). Диапазон хэш-значений или все возможные хэш-значения (т.н. пространство ключей) распределяется между узлами кластера Cassandra. Затем Cassandra назначает каждому элементу данных свой узел, и этот узел отвечает за хранение и управление этим элементом данных. Подробные описание архитектуры Cassandra содержится в документе "Cassandra - A Decentralized Structured Storage System" (Cassandra – децентрализованная структурированная системы хранения данных - см. раздел Ресурсы).

Такая архитектура предоставляет следующие возможности:

  • Cassandra распределяет данные между узлами прозрачно для пользователей. Любой узел может принимать любой запрос (чтение, запись или удаление), и если данные хранятся не в этом узле, перенаправляет его в нужный узел;
  • пользователи могут определить необходимое количество реплик, и Cassandra прозрачно обеспечит создание реплик и управление ими;
  • настраиваемая согласованность: при хранении и считывании данных пользователи могут выбирать уровень согласованности по каждой операции. Например, если при записи или чтении используется уровень согласованности «кворум», то данные записываются и считываются более чем из половины узлов кластера. Поддержка настраиваемой согласованности позволяет выбрать уровень согласованности, наиболее подходящий для данного случая;
  • Cassandra обеспечивает очень быструю запись, более быструю, чем чтение, со скоростью передачи данных порядка 80-360 МБ/с на узел. Это достигается с помощью двух подходов:
    • Cassandra хранит большую часть данных в оперативной памяти ответственного узла, и любые обновления выполняются в памяти, а затем записываются в постоянную систему хранения (файловую систему) ленивым методом. Однако во избежание потери данных Cassandra регистрирует все транзакции в журнале фиксации транзакций на диске. В отличие от обновления элементов данных на диске, записи в журналы фиксации могут только добавляться, что исключает задержку вращения диска. Подробнее о характеристиках дисковых накопителей см. в разделе Ресурсы;
    • если не требуется полная согласованность записей, Cassandra записывает данные в достаточное число узлов без разрешения конфликтов несоответствия, которые разрешаются только при первом считывании. Этот процесс называется «ремонтом при чтении».

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


Возможные сюрпризы Cassandra

При переходе от реляционной базы данных к Cassandra учитывайте следующие различия.

Никаких транзакций, никаких JOIN-операций

Хорошо известно, что Cassandra не поддерживает транзакции ACID. В ней есть пакетные операции, но нет никакой гарантии, что подоперации в составе пакетной операции будут выполнены в атомарном режиме (либо все, либо ничего). Этот вопрос подробнее рассматривается в разделе Сбой операции может оставить след.

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

Нет внешних ключей, и ключи неизменяемы

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

Ключи должны быть уникальными

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

Существует два пути решения этой проблемы. Во-первых, можно использовать составной ключ. Иными словами, создать ключ, объединив несколько полей, и это решение часто применяется для ключей строк. Второе решение: когда есть опасность повторения одного и того же ключа, к ключу добавляется случайное значение или метка времени. Это часто делается с индексами, когда индекс хранит значение в виде имени столбца. Например, в приложении оценки книг в качестве имени столбца используется рейтинг. Чтобы исключить возможность появления записей с одним и тем же именем столбца, к значению рейтинга в качестве суффикса добавляется метка времени.

Сбой операции может оставить след

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

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

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

Усложненный поиск

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

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

  1. Для создания специальных методов поиска программист должен в определенной степени знать механизм индексации и детали системы хранения данных. Поэтому для работы с Cassandra требуются более квалифицированные программисты, чем для работы с реляционными моделями.
  2. Специальные индексы сложны и в большой мере зависят от порядка сортировки. Порядок сортировки может быть одного из двух типов: столбцы всегда сортируются по имени, а порядок сортировки строк работает только с использованием распределителя с сохранением порядка сортировки (см. раздел Ресурсы).
  3. В отличие от реляционных моделей, для добавления нового запроса часто требуются новые индексы и изменения в коде. Для этого разработчик должен анализировать запросы, прежде чем сохранять данные.

Суперстолбцы и распределители, сохраняющие порядок сортировки, не поощряются

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

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

Восстановление после отказа обеспечивается вручную

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

Она помнит удаления

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

Поэтому Cassandra должна помнить, что элемент данных был удален. В версии 0.8 Cassandra сохраняла все данные, даже если они были удалены. Это приводило к росту потребления дискового пространства при операциях с интенсивным обновлением данных. На самом деле нужно помнить не сами удаленные данные, а только факт удаления элемента данных. Это исправление внесено в более поздние версии Cassandra.


Заключение

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

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


Загрузка

ОписаниеИмяРазмер
Пример кода приложения для оценки книгCassandraSample.zip42 КБ

Ресурсы

Научиться

Получить продукты и технологии

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source, Information Management
ArticleID=858505
ArticleTitle=Погружение в СУБД Apache Cassandra
publish-date=03192013