Работающий программист

NoSQL-база данных Cassandra: приступаем к работе

Тэд Ньюард

 

Ted NewardДревние греки рассказывали легенду о Кассандре, дочери троянского царя Приама и царицы Гекубы. Она была одной из красивейших женщин своего времени. Греческий бог Аполлон предложил ей дар провидицы, и она тут же согласилась принять его, но, когда позднее она отвергла домогательства Аполлона, он наложил на нее проклятье: «ты всегда будешь знать правду, но тебе никто не будет верить». Благодаря своему дару предсказания Кассандра предвидела ловушку в Троянском коне, но из-за проклятья никто в Трое не внял ее предупреждениям. Они ввели коня внутрь города и, сами того не желая, впустили в него греков, спрятавшихся в нем, что и привело к падению Трои. Кассандру в качестве трофея привез в Грецию Агамемнон, там она снова предсказала будущее: его (и свою) смерть, но ей опять не поверили — и в действительности их обоих убили.

Гики современных компьютерных наук рассказывают миф о Кассандре немного иначе: как об Apache Cassandra, еще одной NoSQL-базе данных (кстати, весьма популярной) — она используется во многих хорошо известных интернет-компаниях (YouTube, Netflix и др.), а также, по-видимому, в тех компаниях, отчеты которых принимаются на ура. (Ходят слухи, что Кассандра — это обыгрывание образа Дельфийского оракула.)

Кассандра программная может сбить с толку разработчика ничуть не хуже Кассандры троянской. Это «распределенная, децентрализованная, эластично масштабируемая, высокодоступная, отказоустойчивая база данных с открытым исходным кодом, настраиваемой согласованностью и ориентацией на столбцы, причем проект распределенной структуры основан на Amazon Dynamo, а ее модель данных — на Google Bigtable» (источник: «Cassandra: The Definitive Guide», O’Reilly Media, 2010, p. 14).

Иногда мне кажется, что в греческих мифах куда больше смысла, чем в нашей индустрии.

Если разобрать все это на части, мы видим, что:

  • Cassandra предназначена для хранения огромных-преогромных объемов данных (сотен терабайт запросто, и, похоже, этот пример цитируют весьма часто) на множестве машин, соединенных в кольцо, — в противоположность тенденции для реляционных баз данных, где говорят «купи ящик побольше» (для горизонтального, а не вертикального масштабирования);
  • Cassandra имеет модель данных, на первый взгляд похожую на таковую в реляционной базе данных из-за разговоров о столбцах (колонках), их семействах и именованных значениях, но на практике она работает совершенно по-другому.

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

Концептуальный обзор

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

Допустим, к примеру, что мы используем Cassandra для хранения набора объектов людей. В пространстве ключей Earth у нас будет семейство столбцов People, где в свою очередь есть строки, выглядящие так:

RowKey: tedneward
  ColumnName:"FirstName", ColumnValue:"Ted"
  ColumnName:"LastName", ColumnValue:"Neward"
  ColumnName:"Age", ColumnValue:41
  ColumnName:"Title", ColumnValue:"Architect"
RowKey: rickgaribay
  ColumnName:"FirstName", ColumnValue:"Rick"
  ColumnName:"LastName", ColumnValue:"Garibay"
RowKey: theartistformerlyknownasprince
  ColumnName:"Identifier", ColumnValue: <image>
  ColumnName:"Title", ColumnValue:"Rock Star"

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

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

Все это будет иметь больше смысла, когда вы увидите это в действии, так что давайте приступим к запуску Cassandra.

Приступаем к работе

Прежде чем что-либо делать с Cassandra, вы должны установить ее, и здесь лежит первое препятствие: Cassandra, как и рекламировалось, проект с открытым исходным кодом и подобно многим таким проектам написан отнюдь не на одном из языков Microsoft .NET Framework. Cassandra написана на Java и, как таковая, требует установки на ваш компьютер сравнительно современной исполняющей среды Java. Cassandra нормально работает с Java 6 (и фактически в большинстве публикаций в блогах предлагается именно эта версия), но должна прекрасно работать (возможно, даже быстрее) с недавно выпущенной Java 7.

(Если вы никогда раньше не устанавливали Java на свой компьютер, просто введите в любой поисковой системе «Java Runtime Environment 6 (or 7) download» и скачайте нужный установщик для 32- или 64-разрядной Windows в зависимости от того, какая версия ОС установлена у вас. После этого вам понадобится настроить переменную окружения JAVA_HOME так, чтобы она указывала на каталог установки Java Runtime Environment (JRE) — по умолчанию он находится внутри основного каталога C:\Program Files\Java\jre6, — и прописать путь к подкаталогу bin каталога JRE в переменной окружения PATH.)

Затем скачайте двоичные файлы Cassandra с главной страницы Cassandra. К несчастью для всех нас, кто работает в Windows, эти файлы доступны только в формате .tar.gz, которые Windows не понимает. Для распаковки файлов .tar.gz существуют десятки утилит, в том числе gunzip командной строки и tar в Cygwin, если вы хотите попрактиковаться в Unix-Фу на компьютере с Windows. Поместите содержимое Cassandra в удобный для вас каталог, например C:\Prg\apache-cassandra-1.1.0 (на момент написания статьи версия 1.1.0 была самой новой). Далее, как это часто требуется в проектах на Java, вам нужно создать переменную окружения, которая указывает на корень каталога установки Cassandra, поэтому создайте переменную окружения CASSANDRA_HOME, указывающую на C:\Prg\apache-cassandra-1.1.0 (в моем примере).

Если вы слегка ошеломлены столь примитивными условиями, вспомните, что Java-проекты любят работать на множестве платформ (а значит, приходится использовать механизмы, общие для всех платформ, — да, переменные окружения существуют везде, даже на Android). Положительный момент в том, что, если вам когда-нибудь доведется работать с Cassandra на платформе, отличной от Windows, вы будете все то же самое: скачаете Java, получите Cassandra, разархивируете ее файлы и настроите переменные окружения. Увы, это же означает, что наш инструментарий не особо замысловат и не предусматривает никаких GUI.

Поговори с нами, о пророчица!

Это подразумевает переход в каталог установки Cassandra и запуск командного файла cassandra.bat, который находится в подкаталоге bin. Запустите его командой cassandra –f (ключ –f заставляет его выполняться в активном режиме) и вы должны увидеть примерно то, что показано на рис. 1.

Установка Cassandra с помощью файла cassandra.bat
Рис. 1. Установка Cassandra с помощью файла cassandra.bat

По умолчанию Cassandra конфигурируется так, чтобы помещать данные и журналы фиксации (commit logs) в каталог var в корне вашей файловой системы, который Java интерпретирует как C:\. Это больше соответствует духу «юниксизма», но легко перенастраивается в конфигурационном файле conf/cassandra.yaml.

(Возьмите на заметку: компания DataStax Inc. предлагает установщик «все в одном», содержащий как сервер Cassandra, так и JRE, плюс центр операций на основе HTML, доступный для скачивания бесплатно. Если у вас возникают трудности в сборке всех компонентов, попробуйте воспользоваться этим установщиком.)

Выполняемый сервер Cassandra ожидает входящие соединения на порту 9160, а порт 7199 использует для мониторинга Java Management Extensions — своего рода Java-эквивалента Windows Management Instrumentation. Эти порты должны быть доступны клиентским приложениям и утилитам мониторинга Cassandra.

Как только Cassandra готова к работе, можно подключиться к выполняемому экземпляру через интерфейс командной строки Cassandra, запускаемый с помощью файла cassandra-cli.bat, который тоже находится в каталоге bin (рис. 2).

 Подключение к выполняемому экземпляру Cassandra
Рис. 2. Подключение к выполняемому экземпляру Cassandra

Чтобы создать пространство ключей, используйте команду create keyspace TestKS (имя должно быть уникальным), а чтобы создать семейство столбцов в этом пространстве ключей, сначала введите use <keyspace>, а затем create column family <name>. Никаких других определений схемы не требуется — помните с этого момента, что семейство столбцов является набором пар «имя-значение».

Чтобы вставить данные в семейство столбцов, используйте команду set, в которой нужно указать имя семейства столбцов, куда вы собираетесь вставить данные (TestCF), задать ключ для этой строки (TestKey), столбец внутри семейства, используемый в качестве имени для данного значения (column), и значение, сохраняемое там (value). Однако, поскольку Cassandra хранит данные в виде двоичных значений, вам придется указать Cassandra интерпретировать ключ строки, имя столбца и его значение как ASCII-значения, используя встроенную функцию ascii. Таким образом, полная команда set выглядит так:

set TestCF[ascii('TestKey')][ascii('column')]=ascii('value');

Извлечение данных осуществляется аналогично с помощью команды get:

get TestCF[ascii("TestKey")];

Эта команда вернет нечто вроде:

(column=636f6c756d6e, value=76616c7565, timestamp=1338798419726000)

Это демонстрирует, что Cassandra действительно говорит непонятные вещи (по крайней мере, для нас, смертных). Но если вы хорошенько присмотритесь, то заметите, что эти двоичные значения являются ASCII-эквивалентами слов «column» и «value» соответственно).

Самое трудное позади

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

Ну а пока до новых встреч и удачи в кодировании!


Тэд Ньюард (Ted Neward)консультант по архитектуре в компании Neudesic LLC. Автор и соавтор многочисленных книг, в том числе «Professional F# 2.0» (Wrox, 2010), более сотни статей, часто выступает на многих конференциях по всему миру; кроме того, имеет звание Microsoft MVP в области C#. С ним можно связаться по адресу ted@tedneward.com, если вы заинтересованы в сотрудничестве с его группой. Также читайте его блог blogs.tedneward.com.

Выражаю благодарность за рецензирование статьи эксперту Келли Соммерсу (Kelly Sommers).