Una guida a GemFire ​​con Spring Data

1. Panoramica

GemFire ​​è un'infrastruttura di gestione dei dati distribuita ad alte prestazioni che si trova tra il cluster di applicazioni e le origini dati di back-end.

Con GemFire, i dati possono essere gestiti in memoria, il che rende l'accesso più veloce. Spring Data fornisce una facile configurazione e accesso a GemFire ​​dall'applicazione Spring.

In questo articolo, daremo un'occhiata a come possiamo utilizzare GemFire ​​per soddisfare i requisiti di memorizzazione nella cache della nostra applicazione.

2. Dipendenze di Maven

Per utilizzare il supporto Spring Data GemFire, dobbiamo prima aggiungere la seguente dipendenza nel nostro pom.xml:

 org.springframework.data spring-data-gemfire 1.9.1.RELEASE 

L'ultima versione di questa dipendenza può essere trovata qui.

3. Caratteristiche di base di GemFire

3.1. Cache

La cache nel GemFire ​​fornisce i servizi essenziali di gestione dei dati e gestisce la connettività ad altri peer.

La configurazione della cache ( cache.xml ) descrive come verranno distribuiti i dati tra i diversi nodi:

     ...     ... 

3.2. Regioni

Le aree dati sono un raggruppamento logico all'interno di una cache per un singolo set di dati.

In poche parole, una regione ci consente di archiviare i dati in più VM nel sistema senza considerare in quale nodo sono archiviati i dati all'interno del cluster.

Le regioni sono classificate in tre grandi categorie:

  • La regione replicata contiene il set completo di dati su ogni nodo. Offre prestazioni di lettura elevate. Le operazioni di scrittura sono più lente poiché l'aggiornamento dei dati deve essere propagato a ciascun nodo:
  • La regione partizionata distribuisce i dati in modo che ogni nodo memorizzi solo una parte del contenuto della regione. Una copia dei dati viene archiviata su uno degli altri nodi. Fornisce buone prestazioni di scrittura.
  • La regione locale risiede sul nodo membro di definizione. Non c'è connettività con altri nodi all'interno del cluster.

3.3. Interroga la cache

GemFire ​​fornisce un linguaggio di query chiamato OQL (Object Query Language) che ci consente di fare riferimento agli oggetti archiviati nelle aree dati GemFire. Questo è molto simile a SQL nella sintassi. Vediamo come appare una query molto semplice:

SELEZIONA DISTINCT * FROM exampleRegion

QueryService di GemFire fornisce metodi per creare l'oggetto query.

3.4. Serializzazione dei dati

Per gestire la serializzazione-deserializzazione dei dati, GemFire ​​fornisce opzioni diverse dalla serializzazione Java che offre prestazioni più elevate, fornisce una maggiore flessibilità per l'archiviazione e il trasferimento dei dati, inoltre il supporto per diversi linguaggi.

Con questo in mente, GemFire ​​ha definito il formato dati Portable Data eXchange (PDX). PDX è un formato di dati multilingue che fornisce una serializzazione e deserializzazione più rapide, archiviando i dati nel campo denominato a cui è possibile accedere direttamente senza la necessità di deserializzare completamente l'oggetto.

3.5. Esecuzione della funzione

In GemFire, una funzione può risiedere su un server e può essere richiamata da un'applicazione client o da un altro server senza la necessità di inviare il codice della funzione stesso.

Il chiamante può indirizzare una funzione dipendente dai dati a operare su un particolare set di dati o può guidare una funzione dati indipendente a lavorare su un particolare server, membro o gruppo di membri.

3.6. Query continue

Con le query continue, i client si iscrivono a eventi lato server utilizzando il filtro delle query di tipo SQL. Il server invia tutti gli eventi che modificano i risultati della query. La consegna di eventi di query continua utilizza il framework di sottoscrizione client / server.

La sintassi per una query continua è simile alle query di base scritte in OQL. Ad esempio, una query che fornisce i dati di borsa più recenti dalla regione di borsa può essere scritta come:

SELECT * from StockRegion s where s.stockStatus='active';

Per ottenere l'aggiornamento dello stato da questa query, è necessario allegare un'implementazione di CQListener con StockRegion:

   ...  ...  ...   

4. Spring Data GemFire ​​Support

4.1. Configurazione Java

Per semplificare la configurazione, Spring Data GemFire ​​fornisce varie annotazioni per la configurazione dei componenti principali di GemFire:

@Configuration public class GemfireConfiguration { @Bean Properties gemfireProperties() { Properties gemfireProperties = new Properties(); gemfireProperties.setProperty("name","SpringDataGemFireApplication"); gemfireProperties.setProperty("mcast-port", "0"); gemfireProperties.setProperty("log-level", "config"); return gemfireProperties; } @Bean CacheFactoryBean gemfireCache() { CacheFactoryBean gemfireCache = new CacheFactoryBean(); gemfireCache.setClose(true); gemfireCache.setProperties(gemfireProperties()); return gemfireCache; } @Bean(name="employee") LocalRegionFactoryBean getEmployee(final GemFireCache cache) { LocalRegionFactoryBean employeeRegion = new LocalRegionFactoryBean(); employeeRegion.setCache(cache); employeeRegion.setName("employee"); // ... return employeeRegion; } }

Per impostare la cache e la regione GemFire, dobbiamo prima impostare alcune proprietà specifiche. Qui mcast-port è impostato su zero, il che indica che questo nodo GemFire ​​è disabilitato per il rilevamento e la distribuzione multicast. Queste proprietà vengono quindi passate a CacheFactoryBean per creare un'istanza GemFireCache .

Utilizzando il bean GemFireCache , viene creata un'istanza di LocalRegionFatcoryBean che rappresenta la regione all'interno della cache per le istanze Employee .

4.2. Mappatura delle entità

The library provides support to map objects to be stored in GemFire grid. The mapping metadata is defined by using annotations at the domain classes:

@Region("employee") public class Employee { @Id public String name; public double salary; @PersistenceConstructor public Employee(String name, double salary) { this.name = name; this.salary = salary; } // standard getters/setters }

In the example above, we used the following annotations:

  • @Region, to specify the region instance of the Employee class
  • @Id, to annotate the property that shall be utilized as a cache key
  • @PersistenceConstructor, which helps to mark the one constructor that will be used to create entities, in case multiple constructors available

4.3. GemFire Repositories

Next, let's have a look at a central component in Spring Data – the repository:

@Configuration @EnableGemfireRepositories(basePackages = "com.baeldung.spring.data.gemfire.repository") public class GemfireConfiguration { @Autowired EmployeeRepository employeeRepository; // ... }

4.4. Oql Query Support

The repositories allow the definition of query methods to efficiently run the OQL queries against the region the managed entity is mapped to:

@Repository public interface EmployeeRepository extends CrudRepository { Employee findByName(String name); Iterable findBySalaryGreaterThan(double salary); Iterable findBySalaryLessThan(double salary); Iterable findBySalaryGreaterThanAndSalaryLessThan(double salary1, double salary2); }

4.5. Function Execution Support

We also have annotation support available – to simplify working with GemFire function execution.

There are two concerns to address when we make use of functions, the implementation, and the execution.

Let's see how a POJO can be exposed as a GemFire function using Spring Data annotations:

@Component public class FunctionImpl { @GemfireFunction public void greeting(String message){ // some logic } // ... }

We need to activate the annotation processing explicitly for @GemfireFunction to work:

@Configuration @EnableGemfireFunctions public class GemfireConfiguration { // ... }

For function execution, a process invoking a remote function need to provide calling arguments, a function id, the execution target (onServer, onRegion, onMember, etc.):

@OnRegion(region="employee") public interface FunctionExecution { @FunctionId("greeting") public void execute(String message); // ... }

Per abilitare l'elaborazione dell'annotazione di esecuzione della funzione, è necessario aggiungere per attivarla utilizzando le funzionalità di scansione dei componenti di Spring:

@Configuration @EnableGemfireFunctionExecutions( basePackages = "com.baeldung.spring.data.gemfire.function") public class GemfireConfiguration { // ... }

5. conclusione

In questo articolo, abbiamo esplorato le funzionalità essenziali di GemFire ​​ed esaminato il modo in cui le API fornite da Spring Data ne semplificano il lavoro.

Il codice completo per questo articolo è disponibile su GitHub.