Статьи

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

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

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

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

Драйвер Java Cassandra имеет несколько зависимостей . Документация по драйверу Java 2.0 для Apache Cassandra включает страницу « Настройка среды разработки Java», в которой описаны зависимости драйвера Java 2.0 : cassandra-driver-core-2.0.1.jar ( datastax / java-driver 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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
/**
 * 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

1
2
3
4
5
6
7
8
9
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' команды source 'C:\cassandra\cql\examples\createMovie.cql' ( source 'C:\cassandra\cql\examples\createMovie.cql' при условии, что файл находится в указанном каталоге), и это продемонстрировано на следующем снимке экрана ,

cassandraEnhancedMoviesTableCreated

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

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

1
2
3
4
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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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();
   }
}

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
/**
 * 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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
 * 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

01
02
03
04
05
06
07
08
09
10
11
/**
 * 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 в каталоге conf Cassandra позволяет указывать стандартные параметры JVM, используемые Cassandra (такие как параметры определения размера кучи -Xms , -Xmn и -Xmn ), специфичные для HotSpot параметры JVM (такие как -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.

Ссылка: Подключение к Cassandra из Java от нашего партнера JCG Дастина Маркса в блоге Inspired by Actual Events .