Статьи

Подключение к Кассандре с Java

В своем посте  Hello Cassandra я рассмотрел загрузку базы данных Cassandra NoSQL и использование cqlsh для подключения к базе данных Cassandra. В этой статье я расскажу об основах подключения к базе данных Cassandra из Java-клиента.

Хотя  для  доступа к базе данных Cassandra из Java существует  несколько платформ,  в этой статье я буду использовать JAR-файл DataStax Java ClientDataStax Java Драйвер для Apache Cassandra  доступен  на GitHub . На  странице проекта GitHub datastax / java-driver  говорится, что это «драйвер клиента Java для Apache Cassandra», который «работает исключительно с языком запросов Cassandra версии 3 ( CQL3 )» и «лицензирован по  лицензии Apache License версии 2.0 ».

Страница  Java Driver 2.0 для Apache Cassandra  содержит  общий обзор и подробные сведения  об архитектуре драйвера. В  разделе «Написание вашего первого клиента»  представлены списки кода и пояснения, касающиеся  подключения к Cassandra  с помощью драйвера Java и  выполнения операторов CQL  из кода Java. Листинги кода в этом посте являются адаптациями тех примеров, которые применяются к моим примерам.

Драйвер Cassandra Java  имеет  несколько зависимостейJava Driver 2.0 для Apache Cassandra  документации включает в себя страницу под названием  Настройка среды разработки Java ,  которая очерчивает  зависимости Java 2.0 драйвер вCassandra-драйвер-ядро-2.0.1.jar  ( datastax / Java-драйвер 2.0 ),  netty- 3.9.0-Final.jar  ( netty  direct ), guava-16.0.1.jar  ( Guava 16  direct ),  metrics-core-3.0.2.jar  ( Metrics Core ) и  slf4j-api-1.7.5.jar  ( SLF4J прямой ). Я также обнаружил, что мне нужно поместить  LZ4Factory.java  и  snappy -java  в путь к классам.

Следующий листинг кода имеет простой класс с именем  CassandraConnector.

CassandraConnector.java

package com.marxmart.persistence;

import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.Host;
import com.datastax.driver.core.Metadata;
import com.datastax.driver.core.Session;

import static java.lang.System.out;

/**
 * Class used for connecting to Cassandra database.
 */
public class CassandraConnector
{
   /** Cassandra Cluster. */
   private Cluster cluster;

   /** Cassandra Session. */
   private Session session;

   /**
    * Connect to Cassandra Cluster specified by provided node IP
    * address and port number.
    *
    * @param node Cluster node IP address.
    * @param port Port of cluster host.
    */
   public void connect(final String node, final int port)
   {
      this.cluster = Cluster.builder().addContactPoint(node).withPort(port).build();
      final Metadata metadata = cluster.getMetadata();
      out.printf("Connected to cluster: %s\n", metadata.getClusterName());
      for (final Host host : metadata.getAllHosts())
      {
         out.printf("Datacenter: %s; Host: %s; Rack: %s\n",
            host.getDatacenter(), host.getAddress(), host.getRack());
      }
      session = cluster.connect();
   }

   /**
    * Provide my Session.
    *
    * @return My session.
    */
   public Session getSession()
   {
      return this.session;
   }

   /** Close cluster. */
   public void close()
   {
      cluster.close();
   }
}

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

Код с использованием CassandraConnector

/**
 * Main function for demonstrating connecting to Cassandra with host and port.
 *
 * @param args Command-line arguments; first argument, if provided, is the
 *    host and second argument, if provided, is the port.
 */
public static void main(final String[] args)
{
   final CassandraConnector client = new CassandraConnector();
   final String ipAddress = args.length > 0 ? args[0] : "localhost";
   final int port = args.length > 1 ? Integer.parseInt(args[1]) : 9042;
   out.println("Connecting to IP Address " + ipAddress + ":" + port + "...");
   client.connect(ipAddress, port);
   client.close();
}

Пример кода в этом последнем листинге кода указывает узел по умолчанию, а также порт  localhost и порт  9042. Этот номер порта указан в  файле cassandra.yaml,  расположенном в   каталоге apache-cassandra / conf . Документация Cassandra 1.2  содержит страницу в  файле конфигурации cassandra.yaml, в  которой файл cassandra.yaml описывается как «основной файл конфигурации для Cassandra». Кстати, еще один важный файл конфигурации в этом же каталоге —  cassandra-env.sh , который определяет многочисленные параметры JVM для   базы данных Cassandra на основе Java .

Для примеров в этом посте я буду использовать таблицу MOVIES, созданную на следующем языке запросов Cassandra (CQL):

createMovie.cql

CREATE TABLE movies
(
   title varchar,
   year int,
   description varchar,
   mmpa_rating varchar,
   dustin_rating varchar,
   PRIMARY KEY (title, year)
);

Вышеупомянутый файл может быть выполнен в  cqlsh  с помощью команды source 'C:\cassandra\cql\examples\createMovie.cql' ( конечно, при  условии, что файл находится в указанном каталоге), и это продемонстрировано на следующем снимке экрана.

Здесь стоит подчеркнуть одну вещь: столбцы, созданные как  varchar типы данных  , описываются как  text типы данных командой  cqlsh description . Хотя я и создал эту таблицу напрямую  cqlsh, я также мог бы создать таблицу на Java, как показано в следующем листинге кода и соответствующем снимке экрана, который следует за листингом кода.

Создание таблицы Кассандры с драйвером Java

final String createMovieCql =
     "CREATE TABLE movies_keyspace.movies (title varchar, year int, description varchar, "
   + "mmpa_rating varchar, dustin_rating varchar, PRIMARY KEY (title, year))";
client.getSession().execute(createMovieCql);

Приведенный выше код обращается к переменной экземпляра  client. Класс с этой переменной экземпляра, в которой он может существовать, показан ниже.

Оболочка MoviePersistence.java

package dustin.examples.cassandra;

import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Row;

import java.util.Optional;

import static java.lang.System.out;

/**
 * Handles movie persistence access.
 */
public class MoviePersistence
{
   private final CassandraConnector client = new CassandraConnector();

   public MoviePersistence(final String newHost, final int newPort)
   {
      out.println("Connecting to IP Address " + newHost + ":" + newPort + "...");
      client.connect(newHost, newPort);
   }

   /**
    * Close my underlying Cassandra connection.
    */
   private void close()
   {
      client.close();
   }
}

С 
MOVIES
 таблицей, созданной как показано выше (или с помощью 
cqlsh
 или с клиентским кодом Java), следующие шаги должны манипулировать данными, связанными с этой таблицей. В следующем листинге кода показан метод, который можно использовать для записи новых строк в 
MOVIES
 таблицу.
/**
 * Persist provided movie information.
 *
 * @param title Title of movie to be persisted.
 * @param year Year of movie to be persisted.
 * @param description Description of movie to be persisted.
 * @param mmpaRating MMPA rating.
 * @param dustinRating Dustin's rating.
 */
public void persistMovie(
   final String title, final int year, final String description,
   final String mmpaRating, final String dustinRating)
{
   client.getSession().execute(
      "INSERT INTO movies_keyspace.movies (title, year, description, mmpa_rating, dustin_rating) VALUES (?, ?, ?, ?, ?)",
      title, year, description, mmpaRating, dustinRating);
}

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

Запросы с помощью драйвера Java Cassandra

/**
 * Returns movie matching provided title and year.
 *
 * @param title Title of desired movie.
 * @param year Year of desired movie.
 * @return Desired movie if match is found; Optional.empty() if no match is found.
 */
public Optional<Movie> queryMovieByTitleAndYear(final String title, final int year)
{
   final ResultSet movieResults = client.getSession().execute(
      "SELECT * from movies_keyspace.movies WHERE title = ? AND year = ?", title, year);
   final Row movieRow = movieResults.one();
   final Optional<Movie> movie =
        movieRow != null
      ? Optional.of(new Movie(
           movieRow.getString("title"),
           movieRow.getInt("year"),
           movieRow.getString("description"),
           movieRow.getString("mmpa_rating"),
           movieRow.getString("dustin_rating")))
      : Optional.empty();
   return movie;
}

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

Удаление с помощью драйвера Cassandra Java

/**
 * Deletes the movie with the provided title and release year.
 *
 * @param title Title of movie to be deleted.
 * @param year Year of release of movie to be deleted.
 */
public void deleteMovieWithTitleAndYear(final String title, final int year)
{
   final String deleteString = "DELETE FROM movies_keyspace.movies WHERE title = ? and year = ?";
   client.getSession().execute(deleteString, title, year);
}

Как показали примеры из этого поста в блоге, к Cassandra легко получить доступ из приложений Java с помощью драйвера Java. Стоит отметить, что Кассандра  написана на Java . Преимущество этого для разработчиков Java состоит в том, что многие значения конфигурации Cassandra являются параметрами JVM, с которыми разработчики Java уже знакомы.  cassandra-env.sh Файл в Cassandra  conf каталоге позволяет указать  стандартные параметры виртуальной машины Java ,  используемые Кассандры (например, куча размеров параметров  -Xms-Xmx, и  -Xmn), HotSpot специфические параметры виртуальной машины Java  (например  -XX:-HeapDumpOnOutOfMemoryError-XX:HeapDumpPathпараметры настройки сборки мусора , а также параметры сбора мусора лесозаготовок ),  позволяя утверждения ( -ea) и предоставление Cassandra для  удаленного управления JMX .

Говоря о Cassandra и JMX, Cassandra можно отслеживать через JMX, как описано в разделе «Мониторинг с помощью JConsole» в разделе «  Мониторинг кластера Cassandra» . В  отрывке  из книги «Основы мониторинга Кассандры»  также обсуждается использование JMX для мониторинга Кассандры. Поскольку разработчики Java с большей вероятностью знакомы с клиентами JMX, такими как  JConsole  и  VisualVM , это интуитивно понятный подход к мониторингу Cassandra для разработчиков Java.

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

Вывод

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