JDBC-драйвер#
DataGrid поставляется с JDBC-драйверами, которые позволяют обрабатывать распределенные данные непосредственно через JDBC с помощью стандартных SQL-запросов, например SELECT, INSERT, UPDATE или DELETE.
В настоящее время DataGrid поддерживает два драйвера:
легковесный тонкий JDBC-драйвер, который описан в данном разделе;
клиентский JDBC-драйвер, который взаимодействует с кластером с помощью клиентского узла и описан в разделе «Клиентский JDBC-драйвер».
Тонкий JDBC-драйвер#
Тонкий JDBC-драйвер — легковесный драйвер по умолчанию, который предоставляет DataGrid. Чтобы начать использовать драйвер, добавьте ignite-core-2.16.0.jar в classpath приложения.
Драйвер подключается к одному из узлов кластера и перенаправляет все запросы на него для окончательного выполнения. Узел обрабатывает распределение запросов и агрегацию результатов. Затем результат отправляется обратно в клиентское приложение.
Строка подключения JDBC может быть отформатирована с использованием одного из двух шаблонов — URL query или semicolon.
Синтаксис строки подключения:
// Шаблон `URL query`.
jdbc:ignite:thin://<hostAndPortRange0>[,<hostAndPortRange1>]...[,<hostAndPortRangeN>][/schema][?<params>]
hostAndPortRange := host[:port_from[..port_to]]
params := param1=value1[¶m2=value2]...[¶mN=valueN]
// Шаблон `semicolon`.
jdbc:ignite:thin://<hostAndPortRange0>[,<hostAndPortRange1>]...[,<hostAndPortRangeN>][;schema=<schema_name>][;param1=value1]...[;paramN=valueN]
где:
host— обязательный параметр, который определяет хост узла кластера для подключения.port_from— начало диапазона портов для открытия подключения. Если значение параметра не указано, по умолчанию используется10800.port_to— необязательный параметр. Если значение не указано, по умолчанию используется значение параметраport_from.schema— имя схемы для доступа, по умолчанию используетсяPUBLIC. Это имя должно соответствовать стандартуSQL ANSI-99. Необрамленные идентификаторы (non-quoted identifiers) не чувствительны к регистру. Обрамленные идентификаторы (quoted identifiers) чувствительны к регистру. При использовании формата с точкой с запятой (semicolon) схема может быть определена как параметр с именемschema.<params>— необязательные параметры.
Имя класса драйвера — org.apache.ignite.IgniteJdbcThinDriver.
Пример открытия JDBC-подключения к узлу кластера
// Регистрация JDBC-драйвера.
Class.forName("org.apache.ignite.IgniteJdbcThinDriver");
// Открытие JDBC-подключения.
Connection conn = DriverManager.getConnection("jdbc:ignite:thin://xxx.x.x.x");
Примечание
Убедитесь, что вы заключили строку подключения в двойные кавычки (" ") при подключении из среды bash, например: "jdbc:ignite:thin://[address]:[port];user=[username];password=[password]".
Параметры#
В таблице перечислены все параметры, которые поддерживает строка подключения JDBC:
Параметр |
Описание |
Значение по умолчанию |
|---|---|---|
|
Имя пользователя для SQL-подключения. Этот параметр требуется, если на сервере включена аутентификация |
|
|
Пароль для SQL-подключения. Требуется, если на сервере включена аутентификация |
|
|
Определяет, будут ли выполняться распределенные соединения в режиме без совместного размещения |
|
|
Определяет, следует ли принудительно соблюдать порядок соединения таблиц в запросе. Если установлено значение |
|
|
Установите у параметра значение |
|
|
Определяет, закрываются ли серверные курсоры автоматически после получения последней части результирующего набора. Если этот параметр включен, вызов |
|
|
Включает режим Partition Awareness. В этом режиме драйвер пытается определить узлы, на которых расположены запрашиваемые данные, и отправлять запросы именно на эти узлы. Подробнее о режиме написано ниже в разделе «Partition Awareness» |
|
|
Количество уникальных SQL-запросов, которые драйвер хранит локально для оптимизации. При первом выполнении запроса драйвер получает распределение партиций для запрашиваемой таблицы и сохраняет его локально. При следующем запросе этой таблицы драйвер использует сохраненные данные, чтобы определить, куда отправлять запрос. |
|
|
Количество уникальных объектов, представляющих распределение партиций, которые драйвер хранит локально для оптимизации. Подробнее об этом указано в описании предыдущего параметра. |
|
|
Размер буфера отправки сокета. Если установлено значение |
|
|
Размер буфера приема сокета. Если установлено значение |
|
|
Определяет, использовать ли параметр |
|
|
Включает обновления на стороне сервера. При выполнении DML-операции DataGrid извлекает все промежуточные измененные строки и отправляет их инициатору запроса для анализа. Затем он готовит пакеты обновленных значений для отправки на удаленные узлы. |
|
|
Устанавливает количество секунд, в течение которого драйвер ожидает выполнения объекта |
|
|
Устанавливает количество миллисекунд, в течение которого JDBC-клиент ожидает ответа от сервера. Если установлено значение |
|
Примеры строк подключения:
jdbc:ignite:thin://myHost— подключение кmyHostна порту10800со всеми настройками по умолчанию.jdbc:ignite:thin://myHost:11900— подключение кmyHostна пользовательском порту11900со всеми настройками по умолчанию.jdbc:ignite:thin://myHost:11900;user=*****;password=*****— подключение кmyHostна порту11900с учетными данными пользователя для аутентификации.jdbc:ignite:thin://myHost:11900;distributedJoins=true&autoCloseServerCursor=true— подключение кmyHostна порту11900с включенными распределенными соединениями и оптимизациейautoCloseServerCursor.jdbc:ignite:thin://myHost:11900/myschema;— подключение кmyHostна порту11900и доступ к схемеMYSCHEMA.jdbc:ignite:thin://myHost:11900/"MySchema";lazy=false— подключение кmyHostна порту11900с отключенным ленивым выполнением запроса (lazy=false) и доступом кMySchema(учитывается регистр букв в названии схемы).
Несколько конечных точек (endpoints)#
Можно включить автоматическое переключение при разрыве соединения — для этого укажите несколько конечных точек (endpoints) в строке подключения. JDBC-драйвер случайным образом выбирает один из указанных адресов для подключения. Если соединение разрывается, драйвер выбирает другой адрес из списка, пока соединение не будет восстановлено. Если все конечные точки недоступны, драйвер прекращает попытки и генерирует исключение.
Пример использования нескольких адресов в строке подключения
// Регистрация JDBC-драйвера.
Class.forName("org.apache.ignite.IgniteJdbcThinDriver");
// Открытие JDBC-соединения с несколькими конечными точками.
Connection conn = DriverManager
.getConnection("jdbc:ignite:thin://xxx.xxx.x.xx:xxx,yyy.yyy.y.yy:yyy,zzz.zzz.zz.zzz:zzz");
Partition Awareness#
Внимание
Partition Awareness — экспериментальная функция, ее API и архитектура могут измениться до выхода стабильной версии.
Функция Partition Awareness делает JDBC-драйвер «осведомленным» о распределении данных по партициям внутри кластера. Это позволяет драйверу определять узлы, которые хранят запрашиваемые данные, и отправлять запрос непосредственно на эти узлы (если их адреса указаны в конфигурации драйвера). Такая оптимизация может повысить производительность запросов, которые используют affinity-ключи.
Без функции Partition Awareness JDBC-драйвер подключается только к одному узлу, и все запросы выполняются через него. Если данные хранятся на другом узле, запрос перенаправляется внутри кластера, что создает дополнительную сетевую нагрузку. Функция Partition Awareness устраняет промежуточный шаг с помощью отправки запроса сразу на нужный узел.
Чтобы использовать Partition Awareness, укажите адреса всех серверных узлов в свойствах соединения. Драйвер будет направлять запросы на узлы, где хранятся запрашиваемые данные.
Внимание
В текущей версии драйвер не загружает адреса узлов автоматически после установления соединения. При добавлении нового узла в кластер рекомендуется переподключить драйвер и добавить новый адрес в параметры подключения. В противном случае драйвер не сможет отправлять запросы напрямую на новый узел.
Для включения функции Partition Awareness добавьте параметр partitionAwareness=true в строку подключения и укажите несколько конечных точек (endpoints):
Class.forName("org.apache.ignite.IgniteJdbcThinDriver");
Connection conn = DriverManager
.getConnection("jdbc:ignite:thin://xxx.xxx.x.xx,yyy.yyy.y.yy,zzz.zzz.zz.zzz?partitionAwareness=true");
Примечание
Функция Partition Awareness поддерживается только при использовании стандартной affinity-функции.
Подробнее о связанных параметрах partitionAwarenessSQLCacheSize и partitionAwarenessPartitionDistributionsCacheSize написано выше в таблице в разделе «Параметры».
Конфигурация кластера#
Чтобы принимать и обрабатывать запросы от тонкого JDBC-драйвера, узел кластера привязывается к локальному сетевому интерфейсу на порту 10800 и слушает входящие запросы. Чтобы изменить параметры подключения, используйте экземпляр ClientConnectorConfiguration:
<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
<property name="clientConnectorConfiguration">
<bean class="org.apache.ignite.configuration.ClientConnectorConfiguration" />
</property>
</bean>
IgniteConfiguration cfg = new IgniteConfiguration()
.setClientConnectorConfiguration(new ClientConnectorConfiguration());
Поддерживаемые параметры:
Параметр |
Описание |
Значение по умолчанию |
|---|---|---|
|
Имя хоста или IP-адрес для подключения. Если установлено |
|
|
TCP-порт для подключения. Если указанный порт уже используется, DataGrid пытается найти другой доступный порт с помощью свойства |
|
|
Определяет количество портов, к которым следует попытаться подключиться. Например, если у параметра |
|
|
Максимальное количество курсоров, которые могут быть открыты одновременно для одного соединения |
|
|
Количество потоков в пуле, который обрабатывает запросы |
|
|
Размер буфера отправки TCP-сокета. Если установлено значение |
|
|
Размер буфера приема TCP-сокета. Если установлено значение |
|
|
Определяет, использовать ли опцию |
|
|
Тайм-аут ожидания для клиентских подключений. Клиенты автоматически отключаются от сервера после того, как они остаются неактивными в течение настроенного тайм-аута. Если у параметра установлено значение |
|
|
Разрешен ли доступ через JDBC |
|
|
Разрешен ли доступ через тонкий клиент |
|
|
Если SSL включен, разрешены только SSL-подключения клиентов. Узел поддерживает только один режим подключения: |
|
|
Использовать ли фабрику SSL-контекста из конфигурации узла |
|
|
Требуется ли аутентификация клиента |
|
|
Имя класса, который реализует |
|
Тонкий JDBC-драйвер не является потокобезопасным
JDBC-объекты Connections, Statements и ResultSet не являются потокобезопасными. Не используйте операторы (Statement) и результаты (ResultSet) из одного JDBC-соединения в нескольких потоках.
Тонкий JDBC-драйвер защищает от параллелизма (concurrency). Если обнаруживается одновременный доступ, генерируется исключение (SQLException) с сообщением:
"Concurrent access to JDBC connection is not allowed
[ownThread=<guard_owner_thread_name>, curThread=<current_thread_name>]",
SQLSTATE="08006"
Использование SSL#
Тонкий JDBC-драйвер можно настроить для использования SSL для защиты связи с кластером. SSL должен быть настроен и на стороне кластера, и в JDBC-драйвере.
Чтобы включить SSL в JDBC-драйвере, передайте параметр sslMode=require в строке подключения и укажите параметры хранилищ ключей (keystore) и доверенных сертификатов (truststore):
Class.forName("org.apache.ignite.IgniteJdbcThinDriver");
String keyStore = "keystore/node.jks";
String keyStorePassword = "123456";
String trustStore = "keystore/trust.jks";
String trustStorePassword = "123456";
try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1?sslMode=require"
+ "&sslClientCertificateKeyStoreUrl=" + keyStore + "&sslClientCertificateKeyStorePassword="
+ keyStorePassword + "&sslTrustCertificateKeyStoreUrl=" + trustStore
+ "&sslTrustCertificateKeyStorePassword=" + trustStorePassword)) {
ResultSet rs = conn.createStatement().executeQuery("select 10");
rs.next();
System.out.println(rs.getInt(1));
} catch (Exception e) {
e.printStackTrace();
}
Параметры, которые влияют на соединение SSL/TLS:
Параметр |
Описание |
Значение по умолчанию |
|---|---|---|
|
Включает SSL-соединение. Доступно два режима: |
|
|
Название протокола для безопасного соединения. Реализации протокола, которые предоставляются JSSE (Java Secure Socket Extension): |
|
|
Алгоритм управления ключами, который используется для создания диспетчера ключей. В большинстве случаев достаточно значения по умолчанию. Реализации алгоритмов в JSSE: |
|
|
URL-адрес файла хранилища клиентских сертификатов ( |
Значение системного свойства |
|
Пароль от хранилища клиентских сертификатов. Если у параметра |
Значение системного свойства |
|
Тип хранилища клиентских сертификатов, который используется при инициализации SSL-контекста. Если у параметра |
Значение системного свойства |
|
URL-адрес файла хранилища доверенных сертификатов ( |
Значение системного свойства |
|
Пароль от хранилища доверенных сертификатов. Если у параметра |
Значение системного свойства |
|
Тип хранилища доверенных сертификатов. Если у параметра |
Значение системного свойства |
|
Отключает проверку сертификатов сервера. Чтобы доверять любым сертификатам сервера (включая отозванные, просроченные или самоподписанные SSL-сертификаты), установите значение |
|
|
Имя класса пользовательской реализации |
|
Реализация SSL в тонком JDBC-драйвере основана на JSSE и использует два файла хранилища ключей (keystore) Java:
sslClientCertificateKeyStoreUrl— хранилище клиентских сертификатов, которое содержит ключи и сертификат клиента.sslTrustCertificateKeyStoreUrl— хранилище доверенных сертификатов, которое содержит сертификаты для проверки подлинности сервера.
Хранилище доверенных сертификатов — необязательный параметр, но должен быть настроен один из двух параметров: sslTrustCertificateKeyStoreUrl или sslTrustAll.
Использование параметра sslTrustAll
Не включайте параметр sslTrustAll в производственной среде или в сети, которой вы не полностью доверяете (особенно если используется публичный интернет).
Если нет возможности использовать собственную реализацию или метод настройки SSLSocketFactory, можно использовать параметр sslFactory JDBC-драйвера.
Этот параметр должен содержать имя класса, который реализует интерфейс Factory<SSLSocketFactory>. Класс должен быть доступен загрузчику классов JDBC-драйвера.
DataSource#
Объект DataSource используется как развертываемый объект, который можно найти по логическому имени через сервис именования JNDI. JDBC-драйвер реализует класс org.apache.ignite.IgniteJdbcThinDataSource, который поддерживает интерфейс DataSource и позволяет использовать его вместо стандартного JDBC-подключения.
Помимо общих свойств DataSource, IgniteJdbcThinDataSource поддерживает все специфические параметры DataGrid, которые можно передавать в строке подключения JDBC. Например, свойство distributedJoins можно установить и переустановить с помощью метода IgniteJdbcThinDataSource#setDistributedJoins().
Подробнее о IgniteJdbcThinDataSource написано в официальной документации Apache Ignite.
Примеры использования#
Чтобы начать обработку данных в кластере, создайте объект JDBC-соединения одним из способов:
// Открытие JDBC-соединения с помощью `DriverManager`.
Connection conn = DriverManager.getConnection("jdbc:ignite:thin://xxx.xxx.x.xx");
или
// Открытие JDBC-соединения с помощью `DataSource`.
IgniteJdbcThinDataSource ids = new IgniteJdbcThinDataSource();
ids.setUrl("jdbc:ignite:thin://xxx.x.x.x");
ids.setDistributedJoins(true);
Connection conn = ids.getConnection();
После этого можно выполнять стандартные SQL-запросы (SELECT, INSERT, MERGE, UPDATE, DELETE) и использовать DML-операторы для изменения данных.
SELECT#
// Запрос людей определенного возраста с помощью подготовленного выражения (`PreparedStatement`).
PreparedStatement stmt = conn.prepareStatement("select name, age from Person where age = ?");
stmt.setInt(1, 30);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
String name = rs.getString("name");
int age = rs.getInt("age");
// ...
}
Также можно использовать DML-операторы для изменения данных.
INSERT#
// Вставка новой записи в таблицу `Person` с ключом типа `long`.
PreparedStatement stmt = conn
.prepareStatement("INSERT INTO Person(_key, name, age) VALUES(CAST(? as BIGINT), ?, ?)");
stmt.setInt(1, 1);
stmt.setString(2, "John Smith");
stmt.setInt(3, 25);
stmt.execute();
MERGE#
// Объединение (merge) записи в таблицу `Person` с ключом типа `long`.
PreparedStatement stmt = conn
.prepareStatement("MERGE INTO Person(_key, name, age) VALUES(CAST(? as BIGINT), ?, ?)");
stmt.setInt(1, 1);
stmt.setString(2, "John Smith");
stmt.setInt(3, 25);
stmt.executeUpdate();
UPDATE#
// Обновление данных в таблице `Person`.
conn.createStatement().
executeUpdate("UPDATE Person SET age = age + 1 WHERE age = 25");
DELETE#
// Удаление записей из таблицы `Person`.
conn.createStatement().execute("DELETE FROM Person WHERE age = 25");
Потоковая передача данных#
JDBC-драйвер поддерживает потоковую передачу (bulk streaming) данных с помощью команды SET. Подробнее о ней написано в подразделе «SET STREAMING» раздела «Управляющие команды».
Коды ошибок#
JDBC-драйвер передает коды ошибок в классе java.sql.SQLException, что облегчает обработку исключений на стороне приложения. Чтобы получить код ошибки, используйте метод java.sql.SQLException.getSQLState(). Он возвращает строку, которая содержит код ошибки SQLSTATE, определенный стандартами ANSI SQL.
Пример обработки ошибок в JDBC
PreparedStatement ps;
try {
ps = conn.prepareStatement("INSERT INTO Person(id, name, age) values (1, 'John', 'unparseableString')");
} catch (SQLException e) {
switch (e.getSQLState()) {
case "0700B":
System.out.println("Conversion failure");
break;
case "42000":
System.out.println("Parsing error");
break;
default:
System.out.println("Unprocessed error: " + e.getSQLState());
break;
}
}
В таблице ниже описаны все коды ошибок ANSI SQLSTATE, которые поддерживаются в JDBC-драйвере DataGrid. В будущем этот список может быть расширен.
Коды ошибок:
Код |
Описание |
|---|---|
|
Ошибка преобразования данных, например строковое выражение не может быть интерпретировано как число или дата |
|
Недопустимый уровень изоляции транзакции |
|
Драйвер не смог установить соединение с кластером |
|
Соединение находится в закрытом состоянии. Это произошло неожиданно |
|
Соединение отклонено кластером |
|
Ошибка ввода-вывода во время связи с кластером |
|
Недопустимое |
|
Неподдерживаемый тип параметра |
|
Нарушение целостности данных |
|
Недопустимое состояние |
|
Запрашиваемая операция не поддерживается |
|
Конфликт при одновременном обновлении данных |
|
Исключение при разборе SQL-запроса |
|
Внутренняя ошибка. Этот код не определен стандартом ANSI и относится к специфическим ошибкам DataGrid. Подробнее об ошибке написано в сообщении в |