В конце июля вышла версия Apache Ignite 2.1. Apache Ignite — распределенная свободная HTAP-платформа (HTAP — Hybrid Transactional and Analytical Processing, системы, которые могут обрабатывать как транзакционную, так и аналитическую нагрузку) для хранения данных в оперативной памяти и на диске, а также вычислений в реальном времени. Ignite написан на Java и может быть плотно интегрирован с .NET и C++.

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

С Apache Ignite 2.1 можно использовать распределенное дисковое хранилище Apache Ignite Persistent Data Store с поддержкой SQL, первые распределенные алгоритмы машинного обучения, новые функции DDL, и кроме того значительно улучшена поддержка платформ .NET и C++.

Persistent Data Store выводит Apache Ignite в новый сегмент — теперь это не просто in-memory data grid, но полноценная распределенная масштабируемая база данных HTAP с возможностью надежного хранения первичных данных, с поддержкой SQL и обработкой информации в реальном времени.

Apache Ignite PDS — Persistence Data Store


Persistence Data Store — новый компонент платформы, который позволяет использовать для хранения данных не только RAM, но и диск.

Мы вложили столько труда программистов в разработку PDS из-за ограничений классических сторонних СУБД при использовании их в связке с системами, подобными Apache Ignite.

  1. СУБД — узкое место при сохранении данных. С помощью технологий вычисления в памяти и горизонтального масштабирования можно добиться значительно более высоких показателей чтения данных. Но при этом запись останется узким местом, поскольку платформе нужно будет дублировать операции записи в СУБД, которая почти всегда масштабируется намного хуже, если масштабируется вообще. А потребность в быстрой записи иногда может быть выше потребности в быстром чтении. Например, у одного из наших клиентов лишь несколько десятков запросов на чтение в секунду (нужна очень низкая задержка отдачи данных при произвольном чтении), и одновременно с этим десятки тысяч операций записи в секунду, которые необходимо транзакционно сохранить для последующего доступа.
  2. СУБД — единая точка отказа. Кластеры Apache Ignite могут состоять из десятков и сотен узлов, которые резервируют друг друга, обеспечивая безопасность клиентских данных и операций. При этом СУБД в большинстве случаев имеет намного более ограниченные возможности резервирования. Падение СУБД в такой ситуации обойдётся гораздо дороже, станет бОльшим стрессом для компании, чем падение одного или нескольких узлов кластера.
  3. Невозможность одновременно выполнять SQL поверх данных в Ignite и в СУБД. Вы можете выполнять запросы ANSI SQL 99 поверх данных, хранящихся в памяти кластера Apache Ignite, но не можете корректно выполнять подобные запросы, если хотя бы часть данных находится внутри сторонней СУБД. Причина: Apache Ignite не контролирует эту СУБД и не знает, какие данные находятся в ней, а какие нет. Пессимистичная гипотеза, что не все данные находятся в RAM, привела бы к необходимости дублировать каждый запрос в СУБД, что значительно снизило бы производительность (не говоря о необходимости интегрирования со множеством SQL- и NoSQL-решений, каждое из которых имеет свои особенности и ограничения работы с данными, что фактически невыполнимая задача!).
  4. Необходимость прогрева. Чтобы воспользоваться Apache Ignite, нужно сначала загрузить необходимые данные из СУБД в кластер, что при больших объемах данных может занимать колоссальное время. Представьте, сколько будет загружаться в кластер, например, 4 терабайта данных! Apache Ignite не может делать это по мере необходимости без дополнительной, написанной со стороны пользователя логики по тем же причинам, что и в предыдущем пункте.

Реализация PDS позволила нам организовать распределенное, горизонтально масштабируемое хранилище, которое ограничено по объему в первую очередь доступными физическими дисковыми массивами, и которое решает описанные выше проблемы.

  1. PDS масштабируется вместе с кластером. Каждый узел Apache Ignite теперь хранит свой участок данных не только в памяти, но и на диске. Это дает близкую к линейной масштабируемость по производительности операций записи.
  2. PDS поддерживает механизмы отказоустойчивости Apache Ignite. Для эффективного распределения и резервирования данных вы можете использовать тот же коэффициент избыточности и функцию колокации. Проприетарный модуль GridGain также позволит делать резервные online-копии всего дискового пространства. Их можно использовать для последующего восстановления после аварий (DR), либо развернуть на другом кластере, в том числе меньшего размера, для не-real-time аналитики, которая могла бы слишком загрузить основной кластер.
  3. PDS позволяет выполнять SQL-запросы применительно к данным как в памяти, так и на диске. Поскольку Apache Ignite тесно интегрирован с этим хранилищем, платформа имеет исчерпывающую информацию по месторасположению данных и может выполнять «сквозные» SQL-запросы. За счет этого пользователь получает возможность использовать Apache Ignite как Data Lake — хранить большой архив информации, который будет лежать на диске, и при необходимости выполнять запросы с учетом этой информации.
  4. PDS позволяет использовать “lazy run” — загружать данные в память постепенно, по мере необходимости. В таком случае кластер может стартовать практически мгновенно, вхолодную, и по мере обращений к данным они будут постепенно переноситься в RAM. Это позволяет значительно ускорить восстановление после аварии (DR RTO), уменьшает риски для бизнеса, а также облегчает и удешевляет процедуры тестирования и разработки за счет экономии времени на прогреве.

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

Технические детали
Взаимодействие между памятью и диском основано на технологиях, реализованных в Apache Ignite 2.0. Доступное пространство хранения делится на страницы, каждая из которых может содержать 0 и более объектов, либо участок объекта (в тех случаях, когда объект превышает страницу по объему). Страница может располагаться в оперативной памяти с дублированием на диске, либо только на диске.

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

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

Persistence Data Store очень легко включить:

<bean id="ignite.cfg"
      class="org.apache.ignite.configuration.IgniteConfiguration">
    <!-- … -->
    <property name="persistentStoreConfiguration">
        <bean class="org.apache.ignite.configuration.PersistentStoreConfiguration"/>
    </property>
    <!-- … -->
</bean>

или

igniteConfiguration.setPersistentStoreConfiguration(
    new PersistentStoreConfiguration());

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

Резюмируя, Persistent Data Store выводит Apache Ignite в новый сегмент, позволяя пользователям использовать Ignite не только как систему обработки данных, но и как горизонтально масштабируемый слой первичного хранения.

Алгоритмы машинного обучения


В Apache Ignite 2.1 появились первые практически применимые распределенные алгоритмы машинного обучения, основанные на технологиях Apache Ignite 2.0кластеризация методом k-средних (k-means) и множественная линейная регрессия методом наименьших квадратов.

Использовать их достаточно несложно, и это «первые ласточки»: в последующих версиях мы будем добавлять новые алгоритмы, которые можно будет использовать для различных целей.

Пример применения (Java)
KMeansLocalClusterer clusterer =
    new KMeansLocalClusterer(new EuclideanDistance(), 1, 1L);

double[] v1 = new double[] {1959, 325100};
double[] v2 = new double[] {1960, 373200};

DenseLocalOnHeapMatrix points =
    new DenseLocalOnHeapMatrix(new double[][] {v1, v2});

KMeansModel mdl = clusterer.cluster(points, 1);

Integer clusterInx =
    mdl.predict(
        new DenseLocalOnHeapVector(new double[] {20.0, 30.0}));

Моделью распределения данных можно управлять, используя разные реализации матриц и векторов. Так DenseLocalOnHeapMatrix использует хранение данных только на локальном узле в управляемой куче JVM.

DDL


В Apache Ignite 2.1 расширена поддержка DDL. Если в Apache Ignite 2.0 появилась работа с индексами, то новая версия даёт возможность работать с таблицами: CREATE TABLE и DROP TABLE.

CREATE TABLE IF NOT EXISTS Person (
  age int, id int, name varchar, company varchar,
  PRIMARY KEY (name, id))
  WITH "template=replicated,backups=5,affinitykey=id";

DROP TABLE Person;

Таблицы создаются в схеме PUBLIC, для каждой из них создается новый кеш. Таблицы имеют дополнительные настройки, которые можно задавать в разделе WITH:

  • TEMPLATE — основать кеш данной таблицы на указанном кеше, имеются специальные значения PARTITIONED и REPLICATED, которые указывают использовать настройки по умолчанию и соответствующую модель распределения кеша.
  • BACKUPS — количество резервных копий данных — коэффициент избыточности.
  • ATOMICITY — может принимать значения ATOMIC и TRANSACTIONAL, то есть включает или выключает транзакционность на данном кеше.
  • CACHEGROUP — группа, к которой принадлежит кеш.
  • AFFINITYKEY — имя колонки (обязательно должна быть частью PRIMARY KEY!), которую следует использовать как ключ партиционирования для корректной колокации данных.

В будущих релизах планируется добавить возможность задавать колонки как NOT NULL, указывать значения по-умолчанию, параметр AUTO INCREMENT и т.д., а также хотим расширять словарь DDL-выражений.

Группы кешей


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

При этом такие группы будут иметь общий физический кеш, соответственно, и такие его компоненты как affinity-функцию, node filter, режим работы кеша, политику обработки потери партиций, политику утилизации памяти.

И многое другое


Комментарии (5)


  1. blind_oracle
    12.09.2017 08:59
    +1

    Ждём ODBC Schema Exploration и можно будет юзать почти как обычную БД :)


  1. Amelius0712
    12.09.2017 12:45
    +3

    Есть несколько моментов. Давайте пройдемся по пунктам.

    • СУБД — узкое место при сохранении данных
      Непонятно, как PDS решает эту «проблему». Данные все равно на диск писать надо.
    • СУБД — единая точка отказа
      Често говоря, зувучит как спекуляция. Якобы нет масштабируемых отказоустойчивых СУБД.
    • Невозможность одновременно выполнять SQL поверх данных в Ignite и в СУБД
      Аргумент конечно хороший. Но нет ни слова про ACID. SQL — просто язык запросов. Интересно как релизован(и реализован ли ACID в случае работы с PDS)?
    • Необходимость прогрева
      Ну вот вообще непонятно. Прогревать нужно и в случае PDS. А если использовать «lazy-run», то возникает вопрос, зачем мне вообще in-memory. Т.е. если после поднятия некоторое время нода будет работать со скоростью обычной реляционной базы и я могу себе это позволить, то получается что in-memory мне и не нужен. Если же для меня критична скорость работы, то возникает вопрос что случится если(а так и будет) часть данных, необходимых для запроса, лежит на нодах, которые не падали, а часть на только что поднятой. Верно ли, что в таком случае время ответа будет равно времени ответа самой медленной ноды(читай реляционной БД)?


    1. artemshitov Автор
      13.09.2017 13:42

      Добрый день!

      СУБД — узкое место при сохранении данных
      Непонятно, как PDS решает эту «проблему». Данные все равно на диск писать надо.

      Проблема решается через горизонтальное масштабирование. Традиционные реляционные СУБД сложно и дорого масштабировать, и даже когда они масштабируются, они масштабируются на уровень нескольких узлов. Apache Ignite может размещаться на десятках и сотнях узлов, работать на нескольких связанных геораспределенных кластерах, размазывая IO и его издержки.

      СУБД — единая точка отказа
      Често говоря, зувучит как спекуляция. Якобы нет масштабируемых отказоустойчивых СУБД.

      Здесь речь идет, скорее, о классических реляционных СУБД, которые обычно плохо горизонтально масштабируются и имеют ограниченные возможности обеспечения отказоустойчивости при сохранении ACID-гарантий. Если говорить о сравнении с разными классами продуктов для хранения данных, можно привести такую иллюстрацию:


      Здесь замечу также, что Apache Ignite является в том числе распределенной СУБД с поддержкой ACID и SQL, но помимо этого имеется множество других возможностей, которые в СУБД других классов зачастую отсутствуют.

      Невозможность одновременно выполнять SQL поверх данных в Ignite и в СУБД
      Аргумент конечно хороший. Но нет ни слова про ACID. SQL — просто язык запросов. Интересно как релизован(и реализован ли ACID в случае работы с PDS)?

      При использовании PDS гарантии ACID остаются в силе.

      Необходимость прогрева
      Ну вот вообще непонятно. Прогревать нужно и в случае PDS. А если использовать «lazy-run», то возникает вопрос, зачем мне вообще in-memory. Т.е. если после поднятия некоторое время нода будет работать со скоростью обычной реляционной базы и я могу себе это позволить, то получается что in-memory мне и не нужен.

      Ранее в принципе не было возможности стартовать быстро, с диска. У некоторых задач есть потребность после рестарта кластера какое-то время поработать медленно, но начать принимать запросы сразу, и после прогрева получить все преимущества распределенного in-memory. Теперь необходимость такого сценария не блокирует выбор Apache Ignite.

      Обращу внимание, что важными сторонами Ignite является не только In-Memory, но еще, например, горизонтальная масштабируемость и функционал грида. Далее, в зависимости от задачи, от платформы выбирается тот набор функций, который лучше всего подходит задаче.

      Если же для меня критична скорость работы, то возникает вопрос что случится если(а так и будет) часть данных, необходимых для запроса, лежит на нодах, которые не падали, а часть на только что поднятой. Верно ли, что в таком случае время ответа будет равно времени ответа самой медленной ноды(читай реляционной БД)?

      Если часть необходимых для запроса данных лежит на узле, где они еще не поднялись с диска, то они будут прочитаны с диска, время выполнения запроса будет соответствующим. Но такой запрос хотя бы можно будет выполнить. Что важнее для задачи — выполнить любой ценой или выполнить только быстро — зависит от задачи. И для того, и для другого сценария есть инструменты реализации.


      1. Amelius0712
        13.09.2017 14:14

        Ок. Давайте еще разок.

        СУБД — узкое место при сохранении данных. С помощью технологий вычисления в памяти и горизонтального масштабирования можно добиться значительно более высоких показателей чтения данных. Но при этом запись останется узким местом, поскольку платформе нужно будет дублировать операции записи в СУБД, которая почти всегда масштабируется намного хуже, если масштабируется вообще. А потребность в быстрой записи иногда может быть выше потребности в быстром чтении.

        Тщетно пытаюсь нагрепать в оригинальной статье слово «реляционная». Какая-то подмена понятий выходит. Ну да ладно. Так вот, из ответа
        Проблема решается через горизонтальное масштабирование. Традиционные реляционные СУБД сложно и дорого масштабировать, и даже когда они масштабируются, они масштабируются на уровень нескольких узлов. Apache Ignite может размещаться на десятках и сотнях узлов, работать на нескольких связанных геораспределенных кластерах, размазывая IO и его издержки.

        Мне совсем неясно, чем ваше решение лучше той же кассандры(имеется ввиду часть с распределенной записью)? И если уж в оригинале имеется ввиду сравнение именно с реляционной базой, то надо бы об этом написать.
        Здесь замечу также, что Apache Ignite является в том числе распределенной СУБД с поддержкой ACID и SQL, но помимо этого имеется множество других возможностей, которые в СУБД других классов зачастую отсутствуют.

        Короче из текста и таблицы выходит, что у вас 100% ACID со скоростью In-Memory БД и из CAP у вас есть все 3 пункта. Жажду подробностей.


  1. shishmakov
    13.09.2017 12:57

    В кулуарах слышал, что будет ACID, а в статье действительно про это нет. Какие гарантии тогда даёт Ignite?