Um guia para GemFire com Spring Data
1. Visão geral
GemFire é uma infraestrutura de gerenciamento de dados distribuídos de alto desempenho que fica entre o cluster de aplicativos e as fontes de dados de back-end.
Com o GemFire, os dados podem ser gerenciados na memória, o que torna o acesso mais rápido. Spring Data provides an easy configuration and access to GemFire from Spring application.
Neste artigo, vamos dar uma olhada em como podemos usar o GemFire para atender aos requisitos de cache do nosso aplicativo.
2. Dependências do Maven
Para fazer uso do suporte Spring Data GemFire, primeiro precisamos adicionar a seguinte dependência em nossopom.xml:
org.springframework.data
spring-data-gemfire
1.9.1.RELEASE
A versão mais recente desta dependência pode ser encontradahere.
3. Recursos básicos do GemFire
3.1. Cache
O cache no GemFire fornece os serviços essenciais de gerenciamento de dados, além de gerenciar a conectividade com outros pares.
A configuração do cache (cache.xml) descreve como os dados serão distribuídos entre os diferentes nós:
...
...
3.2. Regiões
As regiões de dados são um agrupamento lógico em um cache para um único conjunto de dados.
Simplificando,a region lets us store data in multiple VMs in the system sem considerar em qual nó os dados são armazenados no cluster.
As regiões são classificadas em três grandes categorias:
-
Replicated region contém o conjunto completo de dados em cada nó. Dá um alto desempenho de leitura. As operações de gravação são mais lentas, pois a atualização de dados precisa ser propagada para cada nó:
-
Partitioned region distribui os dados de forma que cada nó armazene apenas uma parte do conteúdo da região. Uma cópia dos dados é armazenada em um dos outros nós. Ele fornece um bom desempenho de gravação.
-
Local region reside no nó do membro de definição. Não há conectividade com outros nós no cluster.
3.3. Consultar o Cache
O GemFire fornece uma linguagem de consulta chamada OQL (Object Query Language) que nos permite fazer referência aos objetos armazenados nas regiões de dados do GemFire. Isso é muito semelhante ao SQL na sintaxe. Vamos ver como uma consulta muito básica se parece:
SELECT DISTINCT * FROM exampleRegion
QueryService de GemFire fornece métodos para criar o objeto de consulta.
3.4. Serialização de Dados
Para gerenciar a desserialização de serialização de dados, o GemFire oferece outras opções além da serialização Java, que oferecem um desempenho mais alto, maior flexibilidade para armazenamento e transferência de dados, além de suporte para diferentes idiomas.
Com isso em mente, a GemFire definiu o formato de dados do Portable Data eXchange (PDX). PDX é um formato de dados em vários idiomas que fornece uma serialização e desserialização mais rápidas, armazenando os dados no campo nomeado que pode ser acessado diretamente sem a necessidade de desserializar completamente o objeto.
3.5. Execução de Função
No GemFire, uma função pode residir em um servidor e pode ser chamada de um aplicativo cliente ou outro servidor sem a necessidade de enviar o próprio código de função.
O chamador pode direcionar uma função dependente de dados para operar em um conjunto de dados específico ou pode levar uma função de dados independente a trabalhar em um servidor, membro ou grupo de membros específico.
3.6. Consulta Contínua
Com consultas contínuas, os clientes assinam eventos do lado do servidor usando a filtragem de consultas do tipo SQL. O servidor envia todos os eventos que modificam os resultados da consulta. A entrega de eventos de consulta contínua usa a estrutura de assinatura do cliente / servidor.
A sintaxe para uma consulta contínua é semelhante às consultas básicas escritas no OQL. Por exemplo, uma consulta que fornece os dados de estoque mais recentes da regiãoStock pode ser escrita como:
SELECT * from StockRegion s where s.stockStatus='active';
Para obter a atualização de status desta consulta, uma implementação deCQListener precisa ser anexada com oStockRegion:
...
...
...
4. Suporte Spring Data GemFire
4.1. Configuração Java
Para simplificar a configuração, o Spring Data GemFire fornece várias anotações para configurar os principais componentes do 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;
}
}
Para configurar o cache e a região do GemFire, primeiro precisamos configurar algumas propriedades específicas. Aquimcast-port é definido como zero, o que indica que este nó GemFire está desabilitado para descoberta e distribuição multicast. Essas propriedades são então passadas paraCacheFactoryBean para criar uma instânciaGemFireCache.
Usando o beanGemFireCache, uma instância deLocalRegionFatcoryBean é criada, representando a região dentro do Cache para as instânciasEmployee.
4.2. Mapeamento de Entidades
A biblioteca fornece suporte para mapear objetos a serem armazenados na grade GemFire. Os metadados do mapeamento são definidos usando anotações nas classes de domínio:
@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
}
No exemplo acima, usamos as seguintes anotações:
-
@*Region*, para especificar a instância de região da classeEmployee
-
@Id, para anotar a propriedade que deve ser utilizada como uma chave de cache
-
@PersistenceConstructor, que ajuda a marcar o único construtor que será usado para criar entidades, no caso de vários construtores disponíveis
4.3. Repositórios GemFire
A seguir, vamos dar uma olhada em um componente central no Spring Data - o repositório:
@Configuration
@EnableGemfireRepositories(basePackages
= "com.example.spring.data.gemfire.repository")
public class GemfireConfiguration {
@Autowired
EmployeeRepository employeeRepository;
// ...
}
4.4. Suporte de consulta Oql
Os repositórios permitem que a definição de métodos de consulta execute com eficiência as consultas OQL na região para a qual a entidade gerenciada é mapeada:
@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. Suporte de execução de função
Também temos suporte à anotação disponível - para simplificar o trabalho com a execução da função GemFire.
Há duas preocupações a serem abordadas quando usamos funções, a implementação e a execução.
Vamos ver como um POJO pode ser exposto como uma função GemFire usando anotações Spring Data:
@Component
public class FunctionImpl {
@GemfireFunction
public void greeting(String message){
// some logic
}
// ...
}
Precisamos ativar o processamento da anotação explicitamente para que@GemfireFunction funcione:
@Configuration
@EnableGemfireFunctions
public class GemfireConfiguration {
// ...
}
Para a execução da função, um processo que invoca uma função remota precisa fornecer argumentos de chamada, uma funçãoid, o destino de execução (onServer,onRegion,onMember, etc.):
@OnRegion(region="employee")
public interface FunctionExecution {
@FunctionId("greeting")
public void execute(String message);
// ...
}
Para ativar o processamento de anotação de execução de função, precisamos adicionar para ativá-lo usando os recursos de varredura de componente do Spring:
@Configuration
@EnableGemfireFunctionExecutions(
basePackages = "com.example.spring.data.gemfire.function")
public class GemfireConfiguration {
// ...
}
5. Conclusão
Neste artigo, exploramos os recursos essenciais do GemFire e examinamos como as APIs fornecidas pela Spring Data facilitam o trabalho com ele.
O código completo para este artigo está disponívelover on GitHub.