Usando o .NET Caching no EF Core por meio de métodos de extensão

Webinar gravado
Ron Hussain e Nick Zulfiqar

O Entity Framework (EF) Core é a nova versão multiplataforma e leve do popular Entity Framework da Microsoft. O EF Core é um mecanismo de mapeamento relacional de objeto para .NET que elimina a necessidade da maior parte do código de acesso a dados que os desenvolvedores escrevem.

O EF Core está sendo cada vez mais usado em aplicativos de servidor de alta transação (ASP.NET, WCF e outros aplicativos de servidor .NET). Além disso, esses aplicativos precisam de escalabilidade para lidar com uma grande quantidade de solicitações de usuários sem diminuir a velocidade. Mas o banco de dados se torna um gargalo e o cache distribuído deve ser usado para eliminar esse gargalo.

Aprenda a usar o cache distribuído como NCache na sua Aplicativos EF Core para remover gargalos de escalabilidade do banco de dados.

Este webinar cobrirá (incluindo exemplos práticos de fontes:

  • Introdução ao EF Core e seus novos recursos (Model, Query, Saving Data)
  • Afunilamentos de escalabilidade de banco de dados no EF Core e como o cache distribuído os resolve
  • Várias opções de uso NCache no EF Core (APIs diretas e métodos de extensão do EF Core)
  • Detalhes do uso dos métodos de extensão do EF Core para armazenamento em cache
  • Como lidar com o armazenamento em cache de coleções e relacionamentos para dados de referência e transacionais?
  • Algumas características importantes de um bom cache distribuído como NCache

O EF Core é um mecanismo de mapeamento relacional de objetos para .NET e .NET Core formulários. Isso permite que os desenvolvedores gerem o código de acesso a dados automaticamente, normalmente teriam que escrever esse código por conta própria. Igual a .NET Core, o EF Core também é multiplataforma e quero dizer que você pode executá-lo no Windows, Linux, Mac e está ficando muito popular entre a comunidade de desenvolvedores.

Neste webinar, falaremos sobre as necessidades de desempenho e escalabilidade em aplicativos EF Core e demonstraremos diferentes estratégias para fazer referência em cache e dados transacionais usando métodos de extensão do EF Core. Quais são os desafios de desempenho e escalabilidade que você enfrentaria em um aplicativo EF Core típico e, em seguida, falaremos sobre várias opções de uso de cache nos aplicativos principais do Entity Framework.

Vou me concentrar principalmente em métodos de extensão, métodos de extensão EF que implementamos para aplicativos principais do Entity Framework. Então, vou passar por todos os métodos de extensão do Entity Framework Core de NCache e então falaremos sobre diferentes estratégias para lidar com dados de referência e dados transacionais como Nick sugeriu. Também veremos como manter os dados sincronizados quando houver dados em dois lugares diferentes quando você começar a usar um cache distribuído. Então, é isso que temos em agenda para o webinar de hoje. Vou começar rapidamente. Temos muito a cobrir. Há muitos exemplos práticos que quero mostrar. Então, vamos começar rapidamente.

O que é Entity Framework / EF Core?

Portanto, o primeiro slide é mais uma introdução ao Entity Framework e ao EF Core.

o que é-entity-framework-core

EF e EF Core, este é um mecanismo de mapeamento relacional de objetos para .NET e .NET core formulários. A versão mais recente do Entity Framework é nomeada como EF Core. Você sabe, recentemente vimos o EF Core 2.1 lançado junto com .NET Core 2.1. Você sabe, ele simplifica sua programação de banco de dados. Você sabe, ele permite que você gere automaticamente seu modelo de acesso a dados. Então, você não precisa escrever isso sozinho. Reduz o esforço de desenvolvimento necessário para isso. Você não precisa escrever código de persistência que normalmente escreveria em um nível ADO.NET e, em seguida, precisa ter mapeamento entre seu modelo de dados e o modelo de objeto. Então, ele simplesmente otimiza isso para você.

Então, é muito flexível. Está ficando muito popular, dentro da comunidade de desenvolvedores e sua plataforma cruzada e é muito popular em .NET e .NET Core Aplicativos, especificamente aplicativos altamente transacionais que lidam com muita carga de solicitação.

Diagrama de arquitetura do Entity Framework

Este é um diagrama de arquitetura do Entity Framework.

diagrama de arquitetura

Você sabe, também se aplica ao EF Core. Existem algumas diferenças entre o EF e o EF Core. O EF Core é leve. Tem abordagem modular. Não há muitos, você não precisa passar por uma instalação completa. Você pode ter uma abordagem modular. Eles o decompuseram em pacotes menores, portanto, você pode trabalhar com o pacote em que está interessado.

Portanto, você não precisa passar pela instalação completa para esse assunto e eles também se livraram do .edmx e desses arquivos de mapeamento. Então, com você sabe, os pacotes NuGet e existem alguns comandos que você executa e gera o modelo para você e, em seguida, você simplesmente trabalha com APIs LINQ to Entities na camada de aplicativo e a abordagem geral permanece a mesma.

O que é escalabilidade?

Normalmente, em um aplicativo EF Core que você conhece, falaremos sobre os requisitos de desempenho e escalabilidade. A escalabilidade é uma capacidade dentro de um aplicativo em que você pode aumentar a quantidade de solicitações que esse aplicativo precisa lidar. Por exemplo, sua carga de usuário aumenta ou os usuários que estão contribuindo para o carregamento de solicitações, essa carga de solicitação cresce em um aplicativo e, se seu aplicativo ficar lento, esse aplicativo não será escalável.

Portanto, alto desempenho sob cargas de pico é o que categorizamos como escalabilidade. Se o seu aplicativo estiver funcionando muito bem, em um milissegundo, latência abaixo de cinco usuários, ele deve ter o mesmo tipo de desempenho, mesmo tipo de latência, latência baixa, digamos, cinco mil usuários ou quinhentos mil usuários e muito de carga de solicitação.

Então, alto desempenho sob alta carga de estresse, sob cargas de pico, é isso que categorizamos como escalabilidade. Núcleo EF.

Quais são os aplicativos que precisam de escalabilidade?

quais-aplicativos-precisam-escalabilidade

Pode ser um aplicativo da Web ASP.NET. ASP.NET ou ASP.NET Core que pode estar lidando com muitos pedidos. Pode ser .NET e .NET Core serviços web, novamente no site. Em seguida, temos os aplicativos de servidor IoT. Novamente pode ser .NET ou .NET Core ou qualquer outro .NET geral e .NET Core Aplicativos que podem estar lidando com muitas solicitações ou usuários em seus próprios domínios.

Então, esses são os candidatos à escalabilidade.

Onde exatamente está o problema de escalabilidade?

Normalmente, EF e EF Core, eles são implantados em um web farm. Se for um aplicativo da Web, eles são dimensionados linearmente. Você não tem problemas de escalabilidade na camada do aplicativo, mas eles sempre precisam conversar com uma fonte de dados relacional de back-end. Pode ser um SQL Server. Pode ser o Oracle Server ou qualquer outro armazenamento de dados compatível com EF ou EF Core. No EF Core, eles têm muitos provedores de dados. Há uma lista de provedores que você pode escolher. Então, você acaba conversando com um banco de dados.

Embora sua camada de aplicativo escale bem, mas esse armazenamento de dados, o banco de dados, o banco de dados relacional se torna uma fonte de contenção. É lento para iniciar porque não está na memória. Embora o EF Core tenha criado um provedor de dados na memória, mas isso é um armazenamento InProc e é para testes locais. Isso facilita seus testes, mas uma vez que seu aplicativo é implantado em produção, você precisa lidar com um banco de dados relacional que é lento e não é dimensionado. É muito bom para armazenamento, mas não é dimensionado quando você realmente precisa dessa escalabilidade em seu aplicativo.

Portanto, é uma única fonte que pode sufocar sob cargas extremas.

A Solução

A solução é muito simples que você comece a usar um sistema de cache perturbado como NCache, para seu aplicativo principal do EF, você o usa em combinação com um banco de dados relacional.

Arquitetura de Implantação

Aqui está a arquitetura de implantação do NCache.

arquitetura de implantação

Em primeiro lugar, está na memória. Então, é super-rápido em comparação. Então você tem vários servidores que estão armazenando, os dados que normalmente permitem buscar da fonte de dados relacional de back-end. Você pode trazê-lo para o cache e pode ser seu ASP.NET ou ASP.NET Core Apps, .NET ou .NET, Web Services ou pode ser .NET ou .NET Core Aplicativos de servidor ou qualquer tipo de .NET ou .NET Core Aplicativos ou mesmo aplicativos Java podem tirar proveito desse sistema de cache distribuído. Ele economiza suas viagens caras para as fontes de dados relacionais. Está na memória. Você pode adicionar mais servidores e aumentar a capacidade desse cluster de cache de maneira linear.

Portanto, não é um único ponto de falha. Não é uma performance, gargalo. Não é um gargalo de escalabilidade. Então, essa é a abordagem recomendada para acompanhá-lo e é isso que abordaremos em grandes detalhes hoje, como usar o cache .NET e isso será NCache como um produto de exemplo em um aplicativo EF Core por meio de métodos de extensão.

3 casos de uso de cache distribuído comumente usados

casos de uso de cache distribuído

Alguns casos de uso comuns de cache distribuído. Você pode usá-lo para cache de dados. Você pode usar chamadas de API diretas. Ou use Entity Framework ou Extension Methods mesmo para EF Core Applications e você economizará suas viagens ao banco de dados o máximo possível.

Então no site, o site das coisas, você tem ASP.NET, ASP.NET Core Cache. Pode ser uma aplicação web ou um serviço web. Se for um aplicativo da Web, se você quiser usar sessões. Você pode querer usar ASP.NET e ASP.NET Core SignalR Backplane, Cache de Resposta para um ASP.NET Core. Da mesma forma, a interface IDistributedCache está disponível, visualize o estado e o cache de saída. Todas essas são opções sem código para seus aplicativos.

E, então, você tem um poderoso Pub/Sub Messaging. Você pode ter um Tópico no qual você se inscreve e depois compartilhar mensagens entre diferentes aplicativos. Publicadores e assinantes podem enviar mensagens entre si.

Então, essa é uma ideia geral. Vamos nos concentrar mais no armazenamento em cache de dados hoje em um aplicativo EF Core e mostrarei etapas simples para começar e, em seguida, expandiremos mais, compartilhando mais e mais detalhes em diferentes cenários.

Então, vamos começar rapidamente com isso.

Cache de dados do APP: Entidades EF Core

A primeira coisa que gostaria de abordar hoje é o Application Data Caching.

what-ef-core-entities-to-cache

Você tem um EF Core Entities. Portanto, essas Entidades precisam ser armazenadas em cache. Assim, você pode ver uma única entidade. Por exemplo, você tem uma contagem, soma. Isso é um valor ou você poderia, você está fazendo alguma classificação e obtém o primeiro cliente ou o critério é tal que está retornando um único cliente, um único produto, um único pedido. Então, essa é uma única entidade, como armazená-la em cache? Da mesma forma, temos os resultados da consulta, pode ser uma coleção de entidades. Então, não é uma entidade única. É uma coleção de entidades. Existem duas opções. Você pode armazenar em cache a coleção inteira como um item no cache ou pode armazenar em cache cada item de coleção, cada entidade dentro dessa coleção separadamente no cache distribuído.

Opções de cache de entidade do EF Core

Então, vamos passar pelas abordagens em torno disso.

opções de cache de entidade efcore

Conforme discutido anteriormente, você pode usar NCache APIs. NCache API é um armazenamento de valor chave, você adiciona dados a NCache você mesmo e, em seguida, você mesmo recebe ou pode usar os métodos de extensão do EF Core e se encarregar disso, entidade única e coleção de entidades.

Então, deixe-me primeiro mostrar-lhe o direto NCache Abordagem de API que é comum para todos os tipos de aplicativos. Você pode usá-lo no EF Core. Você pode usá-lo no EF regular ou em qualquer outro aplicativo .NET e, em seguida, falarei sobre os métodos de extensão do EF Core que são projetados especificamente para seus aplicativos principais do EF e isso torna sua vida muito mais fácil, onde muitas coisas são feitas automaticamente para você e você só precisa chamar esse método de extensão junto com suas consultas. Então, vou mostrar a você essas duas abordagens uma por uma e, em seguida, vamos nos concentrar mais nos métodos de extensão daqui para frente.

Entidade única do EF Core em cache: NCache APIs diretas

Portanto, nosso primeiro exemplo é armazenar em cache a entidade única do EF Core.

Customers GetCustomer (string CustomerId)
{
	string key = "Customer:CustomerId:" + CustomerId;
	Customers customer = (Customers)_cache.Get(key);
	
	if (customer != null)
	{
		return customer;
	}
	else
	{
			customer = (from cust in database.Customers
					where cust.CustomerId == CustomerId
					select cust).FirstOrDefault();
                    _cache.Insert(key, customer);
	
		return customer;
}
}

Temos um método GetCustomer aqui. Vou mostrar isso com a ajuda de um aplicativo de exemplo que formulei para isso. Então, este é o nosso primeiro método. Espero que você possa ver minha tela. Então, temos Get Customer. Está pegando nosso ID de cliente e a ideia aqui é que isso está retornando uma única entidade, certo. Então, normalmente com API direta, o desafio é que você tem que levar em conta ou algo que você tem que implementar sozinho.

Antes de tudo, você precisa ter uma chave e essa chave é algo que você identifica uma entidade dentro NCache e você precisa manter todas as chaves no mesmo formato. Você pode criar um formato de amostra, conforme mostrado na tela. Há uma palavra-chave do cliente e, em seguida, o ID do cliente e um parâmetro de tempo de execução do ID do cliente que faz a chave de cache.

In NCache tudo é armazenado em um par chave-valor. A chave é uma chave de string e o valor é um objeto permitido do .NET e também pode ser qualquer entidade do EF Core, mas você formula a chave e, em seguida, usa a entidade como um objeto a ser armazenado em NCache. Agora você primeiro verifica se essa chave já existe no cache ou não chamando cache.Get e se você conseguir esse cliente diretamente do cache e isso é um NCache API cache.Get, você passa a chave e se pegar aquele cliente você devolve o código daqui, se não for nulo. Mas, se for nulo, por exemplo, você está executando essa consulta pela primeira vez, certo, nada está no cache ainda. Portanto, nesse caso, você executaria no Entity Framework Core, a API LINQ no banco de dados e, em seguida, buscaria esse cliente no banco de dados e também chamaria o cache.Insert, store it with the same key que você formulou e customer is the entidade que você deseja adicionar e, em seguida, também a retorna.

Então, é assim que você realmente lidaria com uma única entidade usando a API certa.

Coleção de entidades principais do EF em cache: NCache APIs diretas

Depois a coleção. A coleção pode ser uma coleção como um único objeto ou novamente como uma única entidade.

List<Customers> GetCustomersByCity (string CustomerCity)
{
	string key = "Customers:City = " + CustomerCity;
	List<Customers> custList;
    custList = (List<Customers>)_cache.Get(key);

	if (custList != null)
	{
		return custList;
	}
	else
	{
		custList = (from cust in database.Customers
					where cust.City == CustomerCity
					select cust).ToList();

		_cache.Insert(key, custList);
		return custList;
	}
} 

Cada entrada de coleção pode ser uma única entidade adicionada separadamente no cache. Então, para isso temos clientes por cidade, então, esse é o próximo método. Está retornando uma lista de clientes. Novamente, é passar a cidade do cliente como critério. Novamente, você formula uma chave. Novamente, você sabe, isso está representando uma coleção de clientes com base na cidade e, em seguida, essa cidade pode ser um parâmetro de tempo de execução aqui. Nova York, Paris, Londres e depois você busca primeiro chamando cache. Pegue você mesmo do cache e depois verifique se ele existe no cache, se existir você volta daqui, se não existir você simplesmente armazena como um única coleção.

Portanto, essa lista de clientes é armazenada como um objeto. Outra alternativa pode ser iterar através da lista de indivíduos, clientes em entidades de clientes e chamar o cache.Insira individualmente conforme mostrado aqui. Certo? Assim, entidades únicas e coleções de entidades usando NCache API como serão armazenadas em cache usando essas abordagens. Agora abordamos as APIs diretas. Isso é algo que você pode usar em qualquer aplicativo.

Entidade única do EF Core em cache: métodos de extensão do EF Core

Vamos nos concentrar nos métodos de extensão do Entity Framework Core. Então, da mesma forma, uma única entidade e uma coleção de entidades usando o NCache métodos de extensão. Então, vou apresentar FromCache.

Customers GetCustomer (string CustomerId)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities
	};
	
	Customers customer  = (from cust in database.Customers
							where cust.CustomerId == CustomerId
							select cust).FromCache(out string cacheKey,
                            options).FirstOrDefault();
	return customer;
}

Esse é o nosso primeiro método de extensão e, a propósito, para que esse método de extensão seja usado, primeiro você precisa apresentar NCache Pacote NuGet Pacote NuGet do Entity Framework Core dentro de seu aplicativo. Então, isso é uma obrigação. Se você for para o instalado, este é um Alachisoft.NCachePacote .EFCore NuGet. Isso é o que você precisa introduzir dentro de seu aplicativo, isso é um e depois disso tudo o que você precisa fazer é, deixe-me, apenas abrir o contexto. Então, dentro do contexto você simplesmente chama NCacheConfiguration.Configure e está recebendo um cacheID que estou lendo nas configurações do aplicativo e, em seguida, também está recebendo o tipo de, se você estiver usando dependências, esse é um recurso avançado nos métodos de extensão do Entity Framework Core. Você precisa fornecer o tipo da fonte de dados.

Mas, uma vez que você ligou NCache Configure o método, existem várias coisas que esse método solicita. Você também pode configurar um registrador, mas é isso. Isso permite que você comece a chamar NCache, EF Core Extension Methods dentro de seu aplicativo.

Coleção de entidades do EF Core em cache: métodos de extensão do EF Core

Então, mesmo que você saiba, método, mas desta vez obtenha o cliente através de métodos de extensão.

List<Customers> GetCustomersByCity (string CustomerCity)
{
	List<Customers> custList; 
	CachingOptions options = new CachingOptions
	{	
		StoreAs = StoreAs.Collection
	};
	custList = (from cust in database.Customers
				where cust.City == CustomerCity
				select cust).FromCache(out string cacheKey,
                options).ToList();
	return custList;	
}

Vai tornar tudo muito mais simples. Você não precisa verificar os dados no cache sozinho e não precisa chamar insert explicitamente e, o mais importante, não precisa chamar, não precisa construir a chave de cache sozinho. Isso é totalmente automatizado como parte da implementação deste 'FromCache'.

Agora, do ponto de vista comportamental, isso é exatamente o que mostramos anteriormente. FromCache, antes de tudo tem uma opção de cache, as opções e 'cacheKey' é uma referência de saída. Portanto, ele constrói a chave de cache automaticamente para você nos bastidores. Você só precisa chamar do cache junto com sua consulta como um método de extensão e simplesmente passar as opções de armazenar isso se, ele sempre retornar uma coleção, certo. Então, nesse caso, você pode escolher ser uma entidade separada ou uma coleção separada, certo. Portanto, pode ser uma coleção de entidades ou entidades separadas dessa coleção.

Assim, FromCache funciona de tal forma que se uma entidade ou se uma consulta que você executou e essas entidades resultantes já estiverem no cache, ele a obteria de NCache automaticamente. Mas, se eles não estiverem no cache, nesse caso, a consulta será executada automaticamente no banco de dados e o conjunto de resultados será retornado e, ao mesmo tempo, também será armazenado em cache e também anexamos o contexto do banco de dados para chamadas subsequentes.

Por exemplo, se você chamar FromCache pela primeira vez, ele o armazenará em cache. Da próxima vez que a mesma consulta for executada, obviamente ela será executada no cache, mas não no banco de dados. Desta vez seu contexto, se isso foi descartado anteriormente e para esta solicitação você estava usando a construção using para esse assunto, se você fizer alguma alteração nas entidades que também anexam essas alterações ao contexto. E quando você chama Save Changes, todas as alterações que foram feitas nessas entidades que foram buscadas no cache são realmente aplicadas no banco de dados. Então, isso é um pouco, novamente um conceito um pouco avançado. Vou gastar um pouco mais de tempo, em um estágio posterior, mas apenas para que você saiba, o método from cache funciona de tal forma que, se algo não estiver no cache, ele irá buscá-lo no banco de dados e armazená-lo em cache. Mas, se algo já estiver disponível no cache, ele apenas retornará de lá. Portanto, isso automatiza toda a abordagem direta da API para você, mas também constrói as chaves. Ele também organiza os dados em uma entidade separada ou em uma coleção separada automaticamente e você só precisa chamar do cache e passar a chave e as opções de saída.

Mesmo caso para coleções. Para uma coleta, obtenha cliente por cidade. Ele seria armazenado como uma coleção e, novamente, você pode chamar do cache. Então, é tão simples começar com os métodos de extensão do Entity Framework Core.

Quais dados armazenar em cache no EF Core?

Nosso próximo tópico está por aí, nosso próximo tópico é novamente sobre o uso do tipo de dados no cache.

quais dados armazenar em cache no efcore

Você pode ter dados de referência ou dados transacionais. Existe uma pergunta?

Sim, Ron, eu tenho uma pergunta aqui. Métodos de extensão de NCache trabalhar com o EF Core, você recomenda .NET Core 2.0 Estrutura ou um .NET Framework?

Tudo bem. Portanto, como o próprio EF Core pode ser executado em .NET, bem como em .NET Core, então, é muito flexível. NCache métodos de extensão funcionariam absolutamente bem. Na verdade, estou executando este aplicativo de exemplo em .NET framework 4.6.1 e eu tenho outro aplicativo de exemplo que está funcionando, acredito .NET core 2.0. Então, isso é .NET Core 2.0. Então, funciona com os dois .NET frameworks e basicamente é preferível que você use .NET Core, mas é flexível. Vai funcionar para ambos. Espero que isso responda sua pergunta.

Seguindo em frente, o próximo segmento da apresentação é quando você começa a planejar o armazenamento em cache corretamente e, obviamente, os métodos de extensão do núcleo da estrutura de entidade tornam sua vida muito mais fácil em termos de armazenamento em cache. Então, ele realmente faz muitas coisas automaticamente. Então, a próxima pergunta é quais dados armazenar em cache, certo?

Então, eu categorizei os dados em duas categorias. Temos dados de referência. Esses são dados de pesquisa e, em seguida, temos nossos dados transacionais, que são criados dinamicamente e mudam com muita frequência. Então, dados de referência, um exemplo rápido seria produtos, funcionários. Não são dados 100% estáticos, mas é algo que não muda com tanta frequência. Mas, muda, a frequência de mudança não é tão grande. E para isso você deve planejar o cache de dados de referência inteiros. Todos os dados de referência devem ser armazenados em cache como uma obrigação e, em seguida, os dados transacionais são dados criados dinamicamente. Como pedidos, contas, algum processamento de fluxo de trabalho em alguma coleção específica de dados e o escopo dessa coleção é apenas para esse fluxo de trabalho. Quando esse fluxo de trabalho concluir a execução, esses dados não serão mais necessários e também poderão ser alterados com muita frequência. Tanto que pode mudar em cinco minutos. Considerando que os dados de referência geralmente são dados de pesquisa que podem mudar entre as horas. 1 a 2 horas, 5 a 10 horas ou mesmo em dias.

Temos uma pergunta aqui. Como você identificaria esse objeto em cache ao recuperar usando EF Extensions assim como as chaves criadas automaticamente? Na verdade, não recuperando, mas excluindo uma chave específica?

Tudo bem. Portanto, temos um método de extensão para recuperação., O método de extensão é executado junto com o EF Core. Portanto, o objeto de retorno seria identificado nas mesmas linhas que sua consulta LINQ o identificaria. A questão eu acho que é mais focada no que acontece quando você planeja atualizar os registros e para isso temos um conjunto de APIs. Damos a você um método que permite gerar uma chave contra uma entidade. Existe um método de geração de chaves que tornamos público. Portanto, antes de fazer uma alteração no cache diretamente e estou assumindo que esta questão está mais focada em excluir algo no cache ou atualizar algo no cache ou remover ou adicionar algo no cache explicitamente. Expusemos a classe de cache que mostrarei em breve e, em seguida, há uma geração de chaves. Novamente, você passa uma string e usa a referência de saída e passa a entidade também. Então, contra essa entidade, usamos a mesma abordagem e forneceremos uma chave e, usando essa chave, você poderá identificar o objeto dessa entidade, se ela existir no cache, você poderá atualizá-la e removê-la.

Acho que no final vou mostrar um exemplo de como conseguir isso, mas apenas para que você saiba, existem métodos aos quais fomos expostos, tire a chave de NCache também. Espero que isso responda sua pergunta.

Cache de dados de referência no EF Core

Se movendo. Então, falamos sobre dados de pesquisa e, em seguida, criamos dados dinamicamente.

cache-reference-data-in-ef-core

Então, vou passar por uma por uma, diferentes abordagens para lidar com isso. Então, primeiro vamos falar sobre dados de referência no EF Core. Como mencionei, isso geralmente é um dado de pesquisa. Então, há duas coisas que você deve fazer como uma obrigação. Você deve primeiro carregar dados inteiros, dados de referência inteiros no cache como uma obrigação e a motivação aqui é que esses dados são algo que não está mudando com tanta frequência. É um catálogo de produtos em um EF, em um aplicativo de e-commerce. Existem alguns descontos em determinados produtos enquanto esse desconto estiver ativado, digamos por três dias. Esses produtos podem não mudar, portanto, é melhor armazenar em cache todos esses produtos em NCache e economize suas viagens caras ao banco de dados para fazer isso o máximo possível. 100%, os dados devem ser carregados no cache. Assim, você não precisa voltar para a fonte de dados e sempre armazená-los em cache como entidades separadas. Por quê? Porque produtos, todo o conjunto de dados pode ser milhares e milhares de produtos.

Digamos, banco de dados Northwind. Os produtos podem variar de 50,000 a 100,000 produtos. Mas, você pode precisar apenas, digamos, 10 desses ou 100 deles para uma determinada solicitação. Portanto, se você armazená-los como entidades separadas, poderá executar consultas LINQ. NCache também suporta LINQ em NCache diretamente. Portanto, você pode executar o LINQ para obter o subconjunto dos dados consultando o subconjunto das entidades de NCache tão bem.

Então, essas são duas regras que você deve seguir como uma obrigação e eu tenho um exemplo e aqui estou apresentando nosso segundo método de extensão chamado Load Into the Cache.

Cache de dados de referência no EF Core: cache de pré-carregamento

Agora, isso funciona dessa maneira e é direcionado apenas para dados de referência. Este é um pré-carregador no cache.

void LoadAllProducts (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities,
	};	
	
	// Loads all products into cache as individual entities
	var res = (from products in database.Products select
    products).LoadIntoCache(options).ToList();
}

Então, a motivação aqui é que você deve chamar esse método, digamos Load All Products e você deve ter certeza de que está armazenando-o como uma entidade separada e deve executar uma consulta que diz de produtos no banco de dados produtos e produtos selecionados . Então, você não está especificando nenhum critério que significa que isso carregaria todos os 60,000 produtos no cache e então você está usando LoadIntoCache, certo. Quando você diz entidades separadas, você só precisa passar essa opção e vamos criar uma entidade separada para cada produto no cache e isso é novamente um pré-carregador, certo. Você deve pré-carregar isso ..

Existem duas opções. Você pode executar um aplicativo separado para isso, que pode assumir a responsabilidade de pré-carregar o cache. Isso pode ser a inicialização do aplicativo ou um aplicativo separado ou pode ser uma implementação do carregador de cache de NCache também. Há um carregador de cache e em versões futuras também estavam trabalhando no atualizador de cache.

A responsabilidade do cache loader é que ele realmente seja executado na inicialização do cache e, em seguida, certifique-se de que todos os dados que você deseja carregar no cache sejam carregados como parte disso. É a sua implementação, mas NCache simplesmente o chama. Mas, como mencionei, você pode criar o método assim e certificar-se de chamá-lo uma vez na inicialização do aplicativo ou ter um aplicativo separado para fazer isso e compartilhar esses dados em todas as instâncias do aplicativo.

Agora, uma vez feito isso, como consultar dados fora do cache e nesse ponto. Vou apresentar meu terceiro método de extensão que é From Cache Only.

Cache de dados de referência no EF Core: dados de referência de pesquisa somente do cache
List<Products> FindDiscontinuedProducts (NorthwindContext database)
{
	//Fetch discontinued products only out of all products 
	List<Products> discontinuedProducts;
	
	discontinuedProducts = (from product in database.Products 
   	 where product.Discontinued == true
   	 select product).FromCacheOnly().ToList();
	
	return discontinuedProducts;

}

Então, o primeiro método de extensão foi FromCache, que era, se algo estiver no cache, pegue-o de lá. Se não estiver, vá automaticamente para o banco de dados e busque-o. LoadIntoCache sempre é executado no banco de dados. Ele nunca é executado no cache, embora esteja retornando, mas está retornando do banco de dados como uma obrigação para que o conjunto de dados seja atualizado. Um novo dado é carregado e, em seguida, também o armazena em cache, e FromCacheOnly está sendo executado apenas em NCache porque isso é projetado apenas para os dados de referência. Portanto, para dados de referência, você usaria uma combinação de LoadIntoCache. Para que todos os dados do conjunto de dados existam no cache como entidades separadas e, em seguida, você chamaria FromCacheOnly para que apenas o conjunto de dados de seu interesse seja, produtos descontinuados, neste caso, trazidos apenas do cache. Portanto, você não precisa acessar o banco de dados. Falarei sobre como manter esses dados atualizados quando os dados forem alterados no banco de dados. Então, espero que isso faça sentido. Deixe-me mostrar-lhe este exemplo aqui.

Então, estou chamando esse método aqui e estou retornando uma lista de produtos, produtos descontinuados usando um EF simples, a API LINQ diretamente no NCache entidades.

Portanto, isso não seria executado no banco de dados. Isso seria executado apenas no cache porque estou usando FromCacheOnly, método de extensão. Eu espero que isso ajude. Cobrimos três métodos de extensão, FromCache, que é mais um caso de uso de dados transacionais e, em seguida, cobrimos LoadIntoCache e FromCacheOnly. Para dados de referência, você deve se concentrar no uso de dados inteiros usando LoadIntoCache e, em seguida, entidades separadas e, em seguida, para consultas, você deve usar FromCacheOnly.

Cache de dados transacionais no EF Core

A seguir, falaremos sobre dados transacionais e, em seguida, falaremos sobre como manter esses dados atualizados tanto para referência quanto para transacionais.

cache-dados-transacionais-no-efcore

Agora, os dados transacionais geralmente são um conjunto de trabalho. Eu já abordei que é um dado criado dinamicamente. É necessário apenas para um usuário atual, solicitação atual ou um fluxo de trabalho em execução e, uma vez executado, você pode não precisar mais desses dados. Portanto, é provável que apenas a instância do aplicativo que realmente recupere esses dados que essas entidades sejam necessárias apenas para essa instância do aplicativo. Portanto, não faz sentido armazenar todos os seus dados transacionais no cache. Não é um requisito. Você deve armazenar em cache apenas o conjunto de trabalho. Então, esse é o passo número um. Portanto, você deve armazenar em cache os resultados da consulta. Você pode buscar entidades de acesso mais fácil e a segunda etapa é que existem duas opções 2a, 2b.

Buscar e armazenar em cache como coleção

Você pode armazenar em cache seus dados transacionais como uma coleção inteira. Essa é uma abordagem preferida.

List<Orders> GetCustomerOrders (string CustomerID)
{
	CachingOptions options = new CachingOptions	
	{
		StoreAs = StoreAs = StoreAs.Collection,
	};

	//Fetch from cache. If not found then fetch from DB.
	orderList = (from customerOrder in database.Orders 
				where customerOrder.Customer.CustomerId==CustomerID 
				select customerOrder)
				.FromCache(out string cacheKey, options).ToList();
	
	return orderList;
}

Normalmente, você precisa sempre de uma coleção inteira, porque está trabalhando nela e também pode armazenar entidades separadas. Depende inteiramente de você e isso é para o cenário em que, embora você tenha armazenado em cache uma coleção, mas ainda a armazene como entidades separadas, porque pode precisar de apenas duas ou três entidades dessa coleção. Portanto, é melhor ter uma abordagem granular ao armazenar as coleções e temos GetCustomerOrders. Ordens são dados bastante transacionais. Deve haver uma unidade de processamento que esteja lidando com determinados pedidos e as chances são de que cada fluxo de trabalho que está fazendo isso tenha seu próprio conjunto de pedidos.

Então, eu vou te mostrar este exemplo bem rápido. Então, está funcionando de tal forma que está colocando muitas opções de cache. Não vamos entrar em detalhes aqui. Armazenar como coleção. É assim que você escolhe armazená-lo como uma coleção e, em seguida, estou usando FromCacheOnly. O motivo dos dados transacionais, estou usando o FromCache porque os dados podem existir no cache e se ele fizer a coleção inteira eu só preciso usá-lo. Eu não tenho que ir para o banco de dados. Mas, se ele não existir no cache e esses dados também forem alterados com muita frequência, também configuramos uma expiração nele, digamos, 30 segundos, então você pode querer voltar ao banco de dados. Se você usar FromCacheOnly, poderá retornar um valor nulo se ele não existir no cache, se já tiver expirado.

Portanto, para dados transacionais, use o método de extensão From Cache, para dados de referência, use LoadIntoCache para pré-carregar e, em seguida, use FromCacheOnly. Então, essa é a abordagem para fazer isso.

Buscar e armazenar em cache como entidades separadas

Para entidades separadas, tudo o que você precisa fazer é armazenar, chamar isso.

List<Orders> GetCustomerOrders (string CustomerID)
{
	CachingOptions options = new CachingOptions	
	{
		StoreAs = StoreAs.SeperateEntities
	};

	//Fetch from cache. If not found then fetch from DB.
	orderList = (from customerOrder in database.Orders 
				where customerOrder.Customer.CustomerId==CustomerID 
				select customerOrder)
				.FromCache(out string cacheKey, options).ToList();
	return orderList;
}

Deixe-me usar isso e em vez de usar uma entidade separada apenas diga, (tenho que comentar deveria ter comentado) Certo, armazene como Entidades Separadas. Isso é tudo o que você precisa fazer.

Então, Ron, enquanto você está analisando isso, há uma pergunta. No exemplo anterior, consultando dados de referência, existe alguma indexação? Porque, só isso é o que você faria no banco de dados para torná-lo….

Absolutamente, essa é uma pergunta muito boa e para dados de referência, já que está sendo executado apenas em cache, essa consulta LINQ exige que seu produto e o atributo estejam ao longo do qual você está executando a consulta LINQ é indexada e, na verdade, eu sou usando dados de índice e é muito simples indexar, você só precisa fornecer o tipo, o modelo e, em seguida, fornecer os atributos que você precisa indexar. Portanto, esses são atributos de índice e, de fato, estamos executando consultas em relação a atributos de índice. Espero que isso responda sua pergunta.

Mantendo o cache atualizado

Vou passar para nossa parte prática bem rápido, mostrar o produto real em ação e, em seguida, o segmento mais importante deste webinar como manter os dados de cache atualizados em comparação com o banco de dados e também em relação aos dados de referência e dados transacionais.

Tudo bem, então eu vou abrir um novo projeto. Certo, então, na parte de demonstração prática, mostrarei rapidamente o produto real em ação para que você saiba como é um armazenamento em cache distribuído e, em seguida, executaremos o aplicativo nele e mostrarei como manter ele fresco, os dados e o cache como frescos.

eu ja instalei NCache em duas das minhas caixas 107 e 108. Vou usá-los como meus servidores de cache e minha máquina pessoal aqui, meu laptop vai atuar como um cliente.

Então, em primeiro lugar, vou lançar o NCache ferramenta de gerenciamento que vem instalada com NCache e eu vou criar um cache, digamos, vamos chamá-lo de cache EF Core. Vou usar dois servidores. Mantenha as réplicas de partição como nossa topologia de cache e depois a opção de replicação assíncrona porque é mais rápida e aqui especifiquei os servidores que hospedarão meu cache. Então, eu tenho dois servidores, demo 1 e demo 2 e porta TCP/IP para comunicação. É tudo orientado pelo TCP/IP no que diz respeito à comunicação entre servidores e clientes.

Tamanho do cache, com base nos dados que você planeja armazenar em cache. Se forem dados de referência, você deve levar em consideração que está carregando todos os produtos, todos os clientes. Da mesma forma, se forem dados transacionais, você precisa considerar o conjunto de trabalho e um pouco mais de espaço para isso também. Mantenha tudo simples, escolha o acabamento e pronto. É assim que é simples começar NCache e configurar um cache.

Como estou executando aplicativos na minha máquina, só preciso adicionar minha caixa como uma máquina cliente. Posso iniciar e testar esse cluster de cache e, depois disso, posso executar o aplicativo de exemplo para conectar-me a ele. Então é assim que é simples. Temos um regular NCache webinar de arquitetura e dimensionamento de aplicativos .NET no qual falamos sobre essas configurações em detalhes. Portanto, se houver alguma dúvida, você também pode pesquisar esses webinars.

Mostrarei alguns aspectos de monitoramento também. janela de estatísticas e então eu vou abrir NCache ferramenta de monitoramento para que eu possa realmente executar o aplicativo da ferramenta de teste de estresse que vem instalado com NCache e ver as coisas em ação. Portanto, esta é uma ferramenta de teste de estresse. Vou executá-lo contra isso porque minha caixa é um cliente, então, posso simplesmente fornecer o nome e ele deve se conectar a isso e devo ser capaz de simular alguma carga fictícia no meu cluster de cache, aí está. O tamanho do cache está crescendo, os itens estão sendo adicionados e as solicitações por segundo de carregamento também estão mostrando atividade nos dois servidores e então essa ferramenta de monitoramento, acho que está demorando, está criando dashboard.

ferramenta de teste de estresse

Então, deixe rolar e, enquanto isso, deixe-me executar outra instância dessa ferramenta no próprio servidor. Foi mal. Tudo bem, então, você pode ver o aumento da quantidade de solicitações por segundo crescendo. Por algum motivo está demorando um pouco para carregar o dashboard, a ferramenta de monitoramento. Acho que vou deixar aqui mesmo assim que voltar mostro os detalhes de monitoramento dessa ferramenta.

Manter o cache atualizado: dados de referência

Tudo bem, nosso próximo segmento neste webinar é manter os dados de cache atualizados em um aplicativo Entity Framework Core e, para isso, usarei novamente dados de referência e exemplo de dados transacionais. Então, vamos começar com dados de referência.

manter-cache-fresh-reference-data

Já estabelecemos que, para armazenar em cache os dados de referência, você deve armazenar em cache todo o conjunto de dados no cache. Por exemplo, você tem produtos, você deve carregar todos os produtos no cache e depois carregá-los como entidades separadas. Então qual é o problema com isso?

Desde, dados de referência, todos os dados de referência no cache e, em seguida, você só usa o cache usando o método de extensão FromCacheOnly. Agora, você não quer pagar um conjunto de dados parcial fora do cache. Se são produtos descontinuados ou você está executando alguns critérios, você quer todos esses produtos no cache. Mas, há chances de que esses produtos realmente mudem no banco de dados. Agora, os dados existem em dois lugares diferentes. Você tem um banco de dados que é sua cópia mestre e, embora tenha carregado dados inteiros no cache, ainda há chances de o banco de dados ser atualizado fora do escopo de seus aplicativos.

Portanto, para manter os dados do cache atualizados, você precisa garantir que tenha algum tipo de mecanismo que atualize os dados e o cache automaticamente e para isso temos duas opções. A opção número um é usar a expiração.

void LoadAllProducts (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities,
	};
	
	options.SetAbsoluteExpiration(DateTime.Now.AddHours(10)); 	
    options.SetResyncProviderName("MyEFCoreResyncProvider");
	
	// Load all products into cache with Expiration and Auto-Reload
	var res = (from products in database.Products select
    products).LoadIntoCache(options).ToList();

}

Esta é uma expiração baseada em tempo e, em seguida, você mistura, você a usa além do recurso de recarga automática. NCache o recurso de expiração permite que você expire dados, remova dados após o período de tempo especificado, digamos, 5 horas, 10 horas e com dados de referência, pois são dados longos e em execução, são dados de pesquisa, dados mestres, portanto, a frequência de alteração não é isso é ótimo, então você pode chegar a um número confortável de horas ou sabe, pode ser 5 horas, 10 horas, 24 horas. Então, com base nisso, você pode configurar um tempo de expiração. Mas, como mencionado anteriormente, você realmente não deseja perder ou remover esses dados do cache.

O que você realmente precisa é que os dados que são alterados, digamos, 10 produtos expiram com base na expiração do que você especificou, ele deve recarregar automaticamente esses dados no cache com o mecanismo de recarregamento automático. E NCache fornece isso com a ajuda de um manipulador de leitura. Então, tudo o que você precisa fazer é carregar novamente os dados inteiros e o cache usando load no cache, usar entidades separadas, mas ao lado disso, use essas características. Como, Definir Expiração Absoluta.

Esse é o valor de expiração que você definiria para todos os produtos que serão carregados no cache e, em seguida, você definirá o provedor de ressincronização, que essencialmente chama seu provedor de leitura dentro NCache. A leitura é combinada com a expiração. Portanto, em vez de remover os dados do cache, ele realmente recarrega, pois conhece todas as chaves e todas as informações relacionadas ao banco de dados, precisamos apenas que você passe o contexto e, com base nesse contexto, chamamos seu provedor de automático e ressincroniza. Obtemos o valor atualizado da fonte de dados.

Deixe-me mostrar-lhe um exemplo de trabalho disso. Aqui está um método. Estou armazenando isso como entidades separadas. Normalmente, eu definiria uma expiração de 5 horas, mas como não temos muito tempo, então, o que eu realmente faria é definir uma expiração de cerca de 30 segundos e colocar um ponto de interrupção aqui e carregar todos os produtos no cache. Eu não configuraria um provedor de ressincronização neste momento apenas para mostrar como funciona a expiração e assim que a expiração entrar em ação, ele removerá os itens do cache e, em seguida, mostrarei como, cuidar desse cenário de tal forma que, em vez de remover, apenas recarregue usando o manipulador de leitura.

Então, usarei o cache local para este bit de amostra. Vou limpar o conteúdo apenas para garantir a segurança e, em seguida, executarei este pedaço de código e atingirei o ponto de interrupção. Direita. Então, ele tem 30 segundos de validade e eu só vou bater e peguei os produtos descontinuados, né. Então, nós temos todos os produtos aqui e temos cerca de mil entradas aqui. Após 30 segundos esses mil itens vão expirar com base nessa expiração absoluta, sinalizador que nós configuramos e eu vou executar essa consulta novamente e você verá que ela não retornaria nada porque não existe nada no cache. Está usando apenas do cache. Então, temos itens expirados. Vou executar isso mais uma vez e você notará que obtive o valor 0.

Portanto, isso não é o recomendado ou o que é preferido, considerando que esses são seus dados de referência, os dados inteiros já estão carregados no cache e você está chamando o método de extensão From Cache Only. Portanto, você precisa de todos os dados disponíveis como uma obrigação, não a resposta parcial ou os dados ausentes e, ao mesmo tempo, isso deve ser recarregado após a expiração. Em vez de removê-lo deve recarregar e é exatamente isso que faremos com a ajuda deste nome Set Resync Provider.

Eu tenho um provedor de ressincronização de amostra, que está bem aqui, IReadThruProvider. O que ele realmente faz é que fornecemos uma implementação padrão disso.

namespace Alachisoft.NCache.EFSampleResyncProvider
{
    public abstract class EFDefaultResyncProvider : IReadThruProvider
    {
        public virtual void Init(IDictionary parameters, string cacheId)
        {
            db = InitializedDbContext();
        }
        public virtual void LoadFromSource(string key, out 					
        ProviderCacheItem cacheItem)
        {
            cacheItem = new ProviderCacheItem(FetchItemFromDb(key));
            cacheItem.AbsoluteExpiration = DateTime.Now.AddHours(10);
            cacheItem.ResyncItemOnExpiration = true;
        }
        public virtual void Dispose()
        {
            db.Dispose();
        }
    }
}

Este é o nosso IReadThruProvider. Tudo o que você precisa fazer é mostrar isso com a ajuda do cache que configuramos. Você precisa configurar o manipulador de leitura. Por exemplo, deixe-me apenas criar um novo cache, deixe-me apenas criar um cache local. Certo. Então, é apenas um cache local. Vou apenas configurar uma fonte de apoio. Habilite a leitura, adicione e digamos EF default e isso precisa ser configurado e eu posso usar isso como um projeto e a implementação já está feita.

Funciona de tal forma que implementei o manipulador IReadThru. Este é o provedor de ressincronização padrão, certo. Tem alguns métodos. Tem inicialização onde você inicializa o contexto do banco de dados. LoadFromSource que é chamado no vencimento e dentro dele estou pegando o item do banco de dados. Se eu entrar na definição, ela realmente cuida de todas as chamadas relacionadas ao banco de dados e isso é algo que estamos fornecendo como parte de nossa implementação. Nosso pacote NuGet o cobre como parte dele. Então, estamos obtendo a chave e com base nessa chave você passa o contexto e o contexto é usado para obter o objeto real diretamente do banco de dados.

Tudo o que você precisa fazer é saber, herdar, implementar este EF Default Resync Provider e fornecer sua própria implementação e nos fornecer o contexto do banco de dados.

Então, esta é uma classe abstrata que demos a você. Você só precisa fornecer o contexto do seu banco de dados Northwind ou qualquer contexto de banco de dados que você tenha e, com base nisso, uma vez que esse método seja substituído / implementado, basta registrá-lo no seu cache. Por exemplo, este é um provedor de ressincronização. Se eu abrir isso, ele contém dois desses. Um é o padrão e o outro é sua implementação e você pode passar sua string de conexão e outras informações, se necessário, e pronto. Você simplesmente implanta isso. Deixe-me apenas levá-lo para este pedaço e isso lhe daria um sucesso nisso. Então, isso tem que ser feito. Como mencionei, isso já é feito como parte do NCache, implementação. Ele tem, o pacote NuGet vem com um provedor de ressincronização que você pode simplesmente implementar implementando este método específico aqui e nos dando o contexto e o resto do trabalho é feito por este provedor de ressincronização padrão de amostra, que realmente funciona nas mesmas linhas que a extensão métodos funcionam.

Construímos sua chave, então sabemos qual chave representa qual entidade e com base nessa entidade e nessa informação chave nós realmente consultamos o banco de dados usando o Entity Framework, APIs. Agora isso já foi feito para o meu cache. O que eu fiz aqui é que eu tenho, ele foi implantado com sucesso. Então, para o meu cache eu já fiz isso. Eu tenho esse padrão do EF e o implantei. Então, vou executar o mesmo caso de uso, mas desta vez, em vez de simplesmente expirar, eu realmente o recarregaria. Então, é isso que eu vou fazer. Tudo o que preciso fazer é configurar o nome do provedor de ressincronização e, como estou planejando atualizar alguns valores também, usarei 60 segundos. Normalmente, para dados de referência, você teria muito mais tempo especificado como sua expiração absoluta, como 5 horas ou até mais. Então, vou executá-lo com 60 segundos e desta vez vejo que meu provedor de ressincronização está configurado.

Então, vou executar este caso de uso mais uma vez e mostrar como isso é atualizado em vez de expirar, em vez de remover. Então, isso foi executado e espero que volte a este ponto. Tudo bem. Então, temos produtos carregados. Vou executar isso mais uma vez e, desta vez, como tem 60 segundos de validade, atualizarei este produto específico, ID do produto 17 e o que faremos é apenas dizer atualizá-lo, tudo bem.

Embora esteja atualizado no banco de dados, ele ainda não seria atualizado no contexto do aplicativo, porque está usando apenas dados de cache e ainda não expirou. Então, continuaremos recebendo os valores mais antigos e se você notar no meu cache que temos milhares de itens e há um Readthru/s, isso mostraria alguma atividade após 60 segundos e chamaria automaticamente o manipulador de leitura que temos acabou de configurar.

Então, deixe-me apenas executá-lo mais uma vez e estou esperando os valores do pedido novamente, se já não for recarregado, mas haveria um ponto em que ele apenas recarregaria e depois disso simplesmente, em vez de expirar, apenas recarregaria o 999 de os produtos. Há um item que é extra, que geralmente é uma referência. Ai está. Então, em vez de expirar, apenas um item expirou porque é uma lista de chaves, caso contrário, todos os dados de referência com base na minha consulta, deixe-me mostrar a consulta, ela diz onde o ID do produto é menor que 1000. Então, na verdade representa 1000 produtos.

Então, vou executar esta consulta mais uma vez e desta vez porque os dados já foram atualizados na expiração, em vez da remoção. Então, estou esperando que o produto atualizado seja adicionado ao cache. Então, lá vai você. Então, meu produto foi atualizado como parte disso. Portanto, é isso que recomendamos como parte de nossa opção número um, que diz que você usa a expiração, mas com o recurso Auto-Reload. Portanto, em vez de expirar, você simplesmente recarrega os dados e isso cuidaria de manter os dados do cache atualizados. Então, você cria um horário confortável que permite manter os dados no cache, você continua obtendo dados mais antigos e, assim que esses dados mais antigos estiverem prestes a expirar, isso pode valer um dia, digamos, 24 horas , pode ser 2 dias, uma semana, o que for mais confortável em sua aplicação. Poderia ser algumas horas também e depois disso apenas recarregaria esses dados no cache.

Então, essa é a nossa opção número um. Espero que tenha sido bem direto.

A opção número dois é que você não usa uma expiração. Então, isso resolveria esse problema aqui, onde os dados sempre existiriam no cache. Mas os dados podem ficar obsoletos no cache e podem ficar obsoletos para sempre. Para isso, você deve recarregar manualmente e isso também é muito simples.

void LoadAllProducts (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities,
	};
		
	var res = (from products in database.Products select
    products).LoadIntoCache(options).ToList();

}

Tudo o que você precisa fazer é chamar isso de Carregar todos os produtos após um intervalo periódico. Por exemplo, se voltarmos a esta parte aqui. Portanto, esse método precisa ser chamado após alguns intervalos e, novamente, como mencionado anteriormente, isso geralmente é feito na inicialização do aplicativo e pode ser um dos aplicativos que está se encarregando disso, que está cuidando de tudo isso. Então, pode ser isso ou pode ser um dos aplicativos, um aplicativo separado que está fazendo isso. Então, pode ser seu aplicativo, uma de suas instâncias de aplicativo ou pode ser um aplicativo separado e esse aplicativo pode chamar esse método periodicamente após, digamos, 5 horas, 24 horas, novamente, qual é o seu tempo confortável após o qual você deseja isso seja executado no banco de dados e você deseja que seus produtos sejam recarregados.

Portanto, LoadIntoCache cuidaria desse cenário específico em que seria executado no banco de dados e carregaria novas cópias no cache. Então, é assim que você se encarrega dos dados de referência. Espero ter sido bem direto.

Mantenha o cache atualizado: dados transacionais

Vamos passar para o próximo segmento onde usamos dados transacionais. Agora, os dados transacionais são algo que dura pouco, certo. É um conjunto de trabalho, como explicado anteriormente. Assim, você pode usar 5 a 10 minutos de expiração. Então, o que você realmente precisa fazer aqui, já que você está usando FromCache que executa no cache, se existir no cache e se não existir no cache, sempre o executará no banco de dados automaticamente. Então, isso está embutido nesse método de extensão, diferente de FromCacheOnly que você usa com o cenário de dados de referência, certo, que é executado apenas no cache. Portanto, não há problema em ter alguns dados disponíveis, se você os armazenou como uma coleção ou como uma entidade separada.

Expiração curta, sem recarga automática
 private List<Orders> GetCustomerOrders (string CustomerID)
{
	CachingOptions options = new CachingOptions	
	{
		StoreAs = StoreAs = StoreAs.Collection
	};
	
	options.SetAbsoluteExpiration(DateTime.Now.AddSeconds(60));

    	List<Orders> orderList = (from customerOrder in database.Orders 					
        where customerOrder.Customer.CustomerId==CustomerID 
        select customerOrder).FromCache(out string cacheKey,
        options).ToList();

	return orderList;
 }

Então, você simplesmente usa expiração curta, digamos 60 segundos, embora eu tenha usado esse exemplo para dados de referência, mas isso foi para esta demonstração em particular, mas para dados de referência você geralmente tem 5 a 10 horas de expiração e para dados transacionais você tem em algum lugar entre 60 segundos ou relacionado, expiração anexada a ele e já que você está usando o From Cache, vamos realmente dar uma olhada no Get Customer Orders, já que você está usando FromCache que deve permitir que você use o, vamos realmente considerar isso como exemplo.

Certo, então, você configura alguma expiração aqui e chama esse método de extensão FromCache e isso deve se encarregar de obtê-lo do banco de dados se ele não existir no cache e depois de algum tempo se você está trabalhando com o conjunto ativo em o cache você obteria do cache, se não estiver ativo no cache, as chances são de que não seja mais necessário, certo. Então, você pode acabar voltando para o banco de dados e isso é a coisa certa a se fazer com dados transacionais. Portanto, espero que isso cubra nossos dados de referência, bem como cenários de dados transacionais e como manter os dados de cache atualizados em relação a esses dois.

Manipulando relacionamentos em cache

Passarei para o nosso próximo segmento, que é o Tratamento de Relacionamentos em Cache.

Rony, tenho algumas perguntas aqui. Será que o NCache ou os itens armazenados em cache residem no NCache servidor ou eles estão sombreados em cada servidor de aplicativos?

Eles residem em NCache. Certo, então os itens realmente existem em NCache, certo. Assim, o repositório real é mantido dentro NCache e, na verdade, construímos as chaves e os objetos junto com esses métodos de entidade. Então, essa é a ideia aqui.

Outra questão é, podemos ter vários carregadores de cache configurados ou todos eles precisam ser configurados em um, quando estávamos adicionando dados de referência ao cache?

Você pode porque carregar no cache é um método genérico, certo. Então, ele realmente carrega o que quer que seja, a consulta que você está planejando executar corretamente. Então, está vinculado à consulta. Você pode ter uma carga múltipla no cache e pode haver um aplicativo separado ou pode ser em locais diferentes dentro do aplicativo. Então, é muito flexível nesse sentido também.

Lidando com relacionamentos em cache: um-muitos

List<Region> GetRegionWithTerritories(NorthwindContext database)
{
	List<Region> regionDetails;
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities
	};

	regionDetails = (from region in database.Region select region)
					.Include(region => region.Territories)
					.FromCache(options).ToList();

	return regionDetails;
}

Existem alguns conceitos importantes que quero destacar. Como lidar com relacionamentos? Um-para-muitos e você sabe, muitos-para-muitos exemplo.

Vamos nos concentrar em um-para-muitos. Se você tem, digamos, regiões e há territórios que fazem parte de regiões e há uma relação de um para muitos acontecendo entre regiões e territórios. Vamos para a abordagem de sincronização e dentro, na verdade, vamos pegar as regiões daqui.

Tudo bem, então, pegue regiões com territórios. A idéia básica aqui é que você tenha a palavra-chave Include e, em seguida, use FromCache e sempre a armazene como uma entidade separada. A ideia aqui é que o item pai da região seja armazenado como um item separado no cache. Uma vez que a região também tem uma relação um-para-muitos com os territórios e há uma coleção de territórios dentro de cada entidade da região, então, NCache obedeceria a isso. Assim que você chamar FromCache, ele simplesmente obterá a região e todas as regiões serão armazenadas como entidades separadas e com base no escopo que você especificar e todos os territórios com a ajuda de FromCache serão armazenados como uma coleção separada dentro de cada região .

Então, é uma entidade que tem muitos lados, o lado da coleção como um objeto relacionado. Então, é assim que você lida com o caso de uso de um para muitos.

Cache de Operações Agregadas

Então você tem Caching Aggregate Operations. Você sabe, você pode resultar em uma entidade ou resultar em um valor.

operações de agregação de cache

Por exemplo, obter um remetente First ou Default, certo. Então, isso é algo, digamos, se eu apenas fizer um First ou Default aqui, isso me traria o primeiro remetente e então você sabe com base nisso, isso será armazenado em NCache.

E da mesma forma, poderia ser a soma da contagem. Pode ser qualquer operação agregada, então, pode ser um valor. Novamente, isso pode ser armazenado em NCache como uma entidade separada.

Shippers GetFirstShipperInstance (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{ 
		StoreAs = StoreAs.Collection
	};

	Shippers shipper = database.Shippers.DeferredFirstOrDefault()
						.FromCache(out string cacheKey, options);

	return shipper;

}

E da mesma forma, poderia ser a soma da contagem. Pode ser qualquer operação agregada, então, pode ser um valor. Novamente, isso pode ser armazenado em NCache como uma entidade separada.

int GetTotalShippersCount (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.Collection 
	};

	int count = database.Shippers.DeferredCount()
				.FromCache(out 	string cacheKey, options);
	
	return count;

}

Arquitetura de cache distribuído

Então, isso abrange nosso webinar no que diz respeito à parte técnica. No final, mostrarei algumas arquiteturas de cache distribuído.

High Availability

NCache como um produto é muito, escalável, rápido. É algo que se baseia na arquitetura peer-to-peer no protocolo. Não existe um único ponto de falha. Você pode adicionar ou remover servidores rapidamente de um cache em execução. Você não precisa parar o cache ou qualquer um dos clientes que estão conectados a ele. Então, dinamicamente, você pode fazer alterações em um cluster de cache em execução.

alta disponibilidade

Topologias de cache

Então nossa topologia mais popular é Cache de réplica de partição. Isso permite que você simplesmente distribua dados em todos os servidores na forma de partições. Então, eles estão agrupando os recursos de memória, recursos computacionais, juntos e isso apresenta uma capacidade lógica e cada servidor também tem um backup. Server1 é backup em 2. Serve2 é backup em 1 e Serve3 é backup em Serve1. Assim, de forma round robin, cada servidor tem um backup em outro servidor.

topologias de cache

Cache do cliente (próximo ao cache)

Da mesma forma, essa é a topologia muito rápida, muito escalável e mais popular. Você também pode ter um cache do cliente que pode ser executado em sua própria caixa de aplicativos. É um cache local, mas está em sincronia com o cache do servidor. O subconjunto dos dados seria trazido automaticamente para o cache e sem nenhuma alteração de código. Isso melhora seu desempenho se seus dados forem principalmente de natureza de referência. Portanto, uma vez que você carregue no cache e comece a chamar esse subconjunto de dados, chamando o cache do cliente FromCacheOnly realmente ajudaria nesse caso.

cliente-cache

Replicação WAN de Cache

Replicação de WAN é outro recurso, a replicação em ponte. Você pode ter sites de dados ativos-passivos ou ativos-ativos. Todos os dados, os dados do EF Core, sessões ASP.NET ou dados regulares podem ser transferidos para o site de destino pela WAN de maneira ativa-passiva ou ativa-ativa. Então, isso é o que NCache cobre como parte dela.

wan-replicação

Conclusão

Só para reiterar, levarei mais um minuto antes de entregá-lo a Nick. Então, falamos sobre entidade única e armazenamento de coleções de entidades usando APIs diretas. Isso foi um pouco diferente em termos de métodos de extensão e então falamos sobre métodos de extensão que eram muito mais simples por natureza e você sabe, mais flexíveis por natureza também. FromCache foi o primeiro método que busca algo do cache se existir, se não existir, ele busca automaticamente da fonte de dados, diferentemente das APIs diretas onde você tem que implementá-lo você mesmo. Ele também constrói as chaves e opções relacionadas que você configura aqui.

Em seguida, falamos sobre dados de referência e transacionais. Para manipular dados de referência, você precisa carregar dados inteiros usando LoadIntoCache e deve chamar FromCacheOnly. LoadIntoCache sempre executa no banco de dados e então você sabe, FromCacheOnly, apenas executa no cache e então falamos sobre dados transacionais que você pode manipular com a ajuda do FromCache e configurar algumas expirações. Dados de referência, para mantê-los atualizados, você precisa usar expirações e, em seguida, usar o recarregamento automático ou não usar expirações e recarregar manualmente usando o LoadIntoCache. Em seguida, falamos sobre dados transacionais, que você precisa criar, algum tipo de expiração e usar FromCache para que, se existir no cache, você o obtenha. Se não existir no cache, você sempre o obtém do banco de dados.

Então, isso conclui nossa apresentação. Por favor, deixe-me saber se há alguma pergunta.

Você sempre pode nos contatar em support@alachisoft.com. Se você tiver alguma dúvida técnica, você também pode entrar em contato conosco via sales@alachisoft.com. Se você quiser dar uma olhada, baixe o produto, você pode ir ao nosso site alachisoft.com e você pode baixar NCache e ele vem com uma versão de teste de 30 dias que você pode usar e se houver alguma dúvida, deixe-nos saber, caso contrário, muito obrigado por participar deste show hoje, o webinar, e nos vemos na próxima. Muito obrigado Rony. Obrigado, pessoal.

O que fazer a seguir?

 
© Copyright Alachisoft 2002 - . Todos os direitos reservados. NCache é uma marca registrada da Diyatech Corp.