Artigos
8
min de leitura
20 de maio de 2021

Como usar o Apache Ignite - Cache - Parte Um

Charles Fonseca
Eu desenvolvo sistemas para facilitar a vida da humanidade.
Mais sobre o autor

Apache Ignite é uma plataforma para computação distribuída desenvolvida pela GridGain, posteriormente doada à Apache Foundation. Esta é uma série de artigos acerca da plataforma Ignite, cujo propósito é contemplar o funcionamento de alto nível, abordando algumas questões internas de implementação.

O Ignite está inserido em diversos contextos: cache, mensageria, streaming, monitoração, eventos, computação distribuída. Todos os módulos serão abordados nesta série. Como subir um cluster e node Ignite está documentado aqui.

Arquitetura de memória

O gerenciamento de memória é um dos diferenciais do Ignite, os dados são mantidos tanto em memória (RAM), quanto em disco.

Caso a instância seja configurada como cache-aside, ou seja, não interage com nenhuma camada de persistência (JDBC, Spring Data, Micronaut Data), ele utilizada os discos dos nodes como detentor da verdade — source of truth — em caso de inconsistência. Caso contrário, um processo chamado change-data-capture process (CDC) é responsável pela sincronização eventual dos dados no cluster.

Quando alocados em memória, parte é destinada on-heap, ou seja, é mantida em memória destinada à instância Java Virtual Machine (JVM) do próprio Ignite — cujo é uma aplicação Java —, o que pode ser desnecessariamente custoso, visto que ao executar o garbage collector ele analisa todo o heap, o que pode roubar alguns bons ciclos de CPU da aplicação. A outra forma é off-heap, fora da memória destinada ao Java, e gerenciado exclusivamente pelo Ignite Segue a representação:

Arquitetura de memória Ignite

Cache

Features

  • Estruturas de dados em cache

O IgniteSet estende o Sete o IgniteQueue estende asinterfaces BlockingQueuepermitem a criação de estruturas de dados completamente distribuídas através de nós, com backup, e particionamento dedicado de forma transparente para os usuários. Como estas estruturas herdam todas as operações em linguagem nativa das implementações Java, elas estão prontamente disponíveis.

  • Implementação para ambas operações síncronas e assíncronas

Todas operações assíncronas implementam a interface IgniteFuture<V> cujo implementação é semelhante ao CompletableFuture do Java, com a possibilidade de inserir função callback, ou encadear operações.

  • Métricas avançadas

A API de cache expõe suas métricas, a quantidade de cache miss, cache hit, put time, get time, tempo de rebalanceamento de dados, tamanho do heap. Isso torna a experiência de usuário bastante transparente, bem como provê uma visão macro ao desenvolvedor.

  • Serialização/deserialização otimizada

IgniteCache<Integer, Organisation>cache = ignite.getOrCreateCache("cacheName");</Integer,>

Organization org = new Organization(

    "Microsoft", new Address("1096 Eddy Street, San Francisco, CA"), OrganizationType.PRIVATE));


cache.put(1, org);


// Obter cache que irá obter valores como objetos binários.

IgniteCache<Integer, BinaryObject>binaryCache = cache.comKeepBinary();// Get recently created organization as a binary object.

BinaryObject binary = binaryCache.get(1);// É assim que a magia acontece

String name = binary.field("nome");

A implementação do BinaryObject.field() nos permite deserializar campos específicos e otimizar o uso da CPU, já que somente os dados a serem utilizados serão processados.

Estruturas de dados distribuídas em cache

  • Queue

IgniteQueue<String> queue = Ignition.ignite().queue("queueName", 0, null);int TIMES = 10;for (int i = 0; i < RETRIES; i++) {

    String item = UUID.randomUUUID() + "_" + i;

    fila.put(item);

    println("Queue item has been added: " + item);

}// IgniteQueue is fully compatible with Java library.

for (String item : queue)

    println("Queue item: " + item);// Take items from queue head.

for (int i = 0; i < TIMES; i++)

    println("Queue item has been read from queue head: " + queue.take());// Take items from queue head once again.

for (int i = 0; i < TIMES; i++)

    println("Queue item has been read from queue head: " + queue.poll());

  • Set

IgniteSet<String> set = Ignition.ignite().set("setName", null);for (int i = 0; i < 5; i++) {

    String item = UUID.randomUUUID() + "_" + i;

    set.add(item);

}for (String item : set)

    println("Set item: " + item); println(set.contains("1")); println("Set size: " + set.size()); println("Removido": " + set.remove("0"));

Recomendações


Obrigado pela leitura!