Рубрики
Без рубрики

Руководство по Apache Ignite

Краткое и практическое руководство по Apache Ignite.

Автор оригинала: baeldung.

1. введение

Apache Ignite-это распределенная платформа с открытым исходным кодом, ориентированная на память. Мы можем использовать его в качестве базы данных, системы кэширования или для обработки данных в памяти.

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

2. Установка и настройка

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

Зависимости Maven для приложения, которое мы собираемся создать:


    org.apache.ignite
    ignite-core
    ${ignite.version}


    org.apache.ignite
    ignite-indexing
    ${ignite.version}

ignite-core является единственной обязательной зависимостью для проекта . Поскольку мы также хотим взаимодействовать с SQL, ignite-indexing также находится здесь. ${ignite.version} – это последняя версия Apache Ignite.

В качестве последнего шага мы запускаем узел воспламенения:

Ignite node started OK (id=53c77dea)
Topology snapshot [ver=1, servers=1, clients=0, CPUs=4, offheap=1.2GB, heap=1.0GB]
Data Regions Configured:
^-- default [initSize=256.0 MiB, maxSize=1.2 GiB, persistenceEnabled=false]

Вывод консоли выше показывает, что мы готовы к работе.

3. Архитектура памяти

Платформа основана на прочной архитектуре памяти . Это позволяет хранить и обрабатывать данные как на диске, так и в памяти. Это повышает производительность за счет эффективного использования ресурсов оперативной памяти кластера.

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

Прочная архитектура памяти разбивается на блоки фиксированного размера, называемые страницами. Страницы хранятся вне кучи Java и организованы в оперативной памяти. Он имеет уникальный идентификатор: Полная страница .

Страницы взаимодействуют с памятью с помощью абстракции Page Memory .

Это помогает читать, писать страницу, а также выделять идентификатор страницы. Внутри памяти Ignite связывает страницы с Буферами памяти .

4. Страницы Памяти

Страница может иметь следующие состояния:

  • Выгружено – буфер страниц не загружен в память
  • Очистить – буфер страниц загружается и синхронизируется с данными на диске.
  • Durty – буфер страницы содержит данные, отличные от данных на диске
  • Грязный в контрольной точке – есть еще одна модификация, которая запускается до того, как первая сохранится на диске. Здесь запускается контрольная точка, и Память страниц сохраняет два буфера памяти для каждой Страницы.

Долговременная память выделяет локальный сегмент памяти, называемый Областью данных . По умолчанию он имеет емкость 20% памяти кластера. Конфигурация нескольких областей позволяет хранить полезные данные в памяти.

Максимальная емкость области-это сегмент памяти. Это физическая память или непрерывный массив байтов.

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

Индексы SQL и кэша хранятся в структурах, известных как деревья B+. Ключи кэша упорядочены по их значениям ключей.

5. Жизненный цикл

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

Давайте рассмотрим типы событий жизненного цикла:

  • BEFORE_NODE_START – перед запуском узла Ignite
  • AFTER_NODE_START – срабатывает сразу после запуска узла Ignite
  • BEFORE_NODE_STOP – перед началом остановки узла
  • AFTER_NODE_STOP – после остановки узла воспламенения

Чтобы запустить узел воспламенения по умолчанию:

Ignite ignite = Ignition.start();

Или из файла конфигурации:

Ignite ignite = Ignition.start("config/example-cache.xml");

В случае, если нам нужно больше контроля над процессом инициализации, есть другой способ с помощью интерфейса LifecycleBean :

public class CustomLifecycleBean implements LifecycleBean {
 
    @Override
    public void onLifecycleEvent(LifecycleEventType lifecycleEventType) 
      throws IgniteException {
 
        if(lifecycleEventType == LifecycleEventType.AFTER_NODE_START) {
            // ...
        }
    }
}

Здесь мы можем использовать типы событий жизненного цикла для выполнения действий до или после запуска/остановки узла.

Для этой цели мы передаем экземпляр конфигурации с пользовательским компонентом жизненного цикла в метод start:

IgniteConfiguration configuration = new IgniteConfiguration();
configuration.setLifecycleBeans(new CustomLifecycleBean());
Ignite ignite = Ignition.start(configuration);

6. Сетка Данных В Памяти

Ignite data grid-это распределенное хранилище ключей , очень знакомое для секционированных HashMap . Он масштабируется по горизонтали. Это означает, что мы добавляем больше узлов кластера, больше данных кэшируется или хранится в памяти.

Это может обеспечить значительное повышение производительности стороннего программного обеспечения, такого как NoSQL, базы данных RDMS, в качестве дополнительного уровня для кэширования.

6.1. Поддержка кэширования

API доступа к данным основан на спецификации JCache JSR 107.

В качестве примера давайте создадим кэш с помощью конфигурации шаблона:

IgniteCache cache = ignite.getOrCreateCache(
  "baeldingCache");

Давайте посмотрим, что здесь происходит, для получения более подробной информации. Во-первых, Ignite находит область памяти, в которой хранится кэш.

Затем страница индекса дерева B+ будет расположена на основе хэш-кода ключа. Если индекс существует, то будет расположена страница данных соответствующего ключа.

Когда индекс равен НУЛЮ, платформа создает новую запись данных с помощью данного ключа.

Далее, давайте добавим некоторые объекты Employee :

cache.put(1, new Employee(1, "John", true));
cache.put(2, new Employee(2, "Anna", false));
cache.put(3, new Employee(3, "George", true));

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

Когда страница индекса не существует, запрашивается новая страница и добавляется в дерево.

Затем страница данных присваивается странице индекса.

Чтобы прочитать сотрудника из кэша, мы просто используем значение ключа:

Employee employee = cache.get(1);

6.2. Поддержка потоковой передачи

Потоковая передача данных в памяти обеспечивает альтернативный подход для приложений обработки данных на основе дисков и файловых систем. Потоковый API разбивает поток данных с высокой нагрузкой на несколько этапов и направляет их для обработки .

Мы можем изменить наш пример и передать данные из файла. Во-первых, мы определяем поток данных:

IgniteDataStreamer streamer = ignite
  .dataStreamer(cache.getName());

Затем мы можем зарегистрировать преобразователь потока, чтобы отметить принятых сотрудников как занятых:

streamer.receiver(StreamTransformer.from((e, arg) -> {
    Employee employee = e.getValue();
    employee.setEmployed(true);
    e.setValue(employee);
    return employee;
}));

В качестве заключительного шага мы повторяем employees.txt строки файлов и преобразование их в объекты Java:

Path path = Paths.get(IgniteStream.class.getResource("employees.txt")
  .toURI());
Gson gson = new Gson();
Files.lines(path)
  .forEach(l -> streamer.addData(
    employee.getId(), 
    gson.fromJson(l, Employee.class)));

С использованием стример.добавить Данные() поместите объекты сотрудников в поток.

7. Поддержка SQL

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

Мы можем подключиться либо с помощью чистого SQL API, либо с помощью JDBC. Синтаксис SQL здесь-ANSI-99, поэтому поддерживаются все стандартные функции агрегирования в запросах, операциях языка DML, DDL.

7.1. JDBC

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

Для этой цели мы регистрируем драйвер JDBC и открываем соединение в качестве следующего шага:

Class.forName("org.apache.ignite.IgniteJdbcThinDriver");
Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1/");

С помощью стандартной команды DDL мы заполняем таблицу Employee :

sql.executeUpdate("CREATE TABLE Employee (" +
  " id LONG PRIMARY KEY, name VARCHAR, isEmployed tinyint(1)) " +
  " WITH \"template=replicated\"");

После ключевого слова WITH мы можем установить шаблон конфигурации кэша. Здесь мы используем REPLICATED . По умолчанию режим шаблона СЕКЦИОНИРОВАН . Чтобы указать количество копий данных, мы также можем указать здесь параметр BACKUP , который по умолчанию равен 0.

Затем давайте сложим некоторые данные с помощью инструкции INSERT DML:

PreparedStatement sql = conn.prepareStatement(
  "INSERT INTO Employee (id, name, isEmployed) VALUES (?, ?, ?)");

sql.setLong(1, 1);
sql.setString(2, "James");
sql.setBoolean(3, true);
sql.executeUpdate();

// add the rest

После этого мы выбираем записи:

ResultSet rs 
  = sql.executeQuery("SELECT e.name, e.isEmployed " 
    + " FROM Employee e " 
    + " WHERE e.isEmployed = TRUE ")

7.2. Запрос объектов

Также можно выполнить запрос по объектам Java, хранящимся в кэше . Ignite обрабатывает объект Java как отдельную запись SQL:

IgniteCache cache = ignite.cache("baeldungCache");

SqlFieldsQuery sql = new SqlFieldsQuery(
  "select name from Employee where isEmployed = 'true'");

QueryCursor> cursor = cache.query(sql);

for (List row : cursor) {
    // do something with the row
}

8. Резюме

В этом уроке мы быстро ознакомились с проектом Apache Ignite. В этом руководстве освещаются преимущества платформы по сравнению с другими аналогичными продуктами, такими как повышение производительности, долговечность, легкие API.

В результате мы узнали, как использовать язык SQL и Java API для хранения, извлечения и потоковой передачи данных внутри сетки сохранения или в памяти.

Как обычно, полный код этой статьи доступен на GitHub .