Uso del almacenamiento en caché de .NET en EF Core a través de métodos de extensión

Seminario web grabado
Ron Hussain y Nick Zulfiqar

Entity Framework (EF) Core es la nueva versión multiplataforma y liviana del popular Entity Framework de Microsoft. EF Core es un motor de mapeo relacional de objetos para .NET que elimina la necesidad de la mayor parte del código de acceso a datos que los desarrolladores escriben de otro modo.

EF Core se usa cada vez más en aplicaciones de servidor de transacciones elevadas (ASP.NET, WCF y otras aplicaciones de servidor .NET). Y estas aplicaciones necesitan escalabilidad para manejar una gran cantidad de solicitudes de usuarios sin ralentizarse. Pero la base de datos se convierte en un cuello de botella y se debe utilizar el almacenamiento en caché distribuido para eliminar este cuello de botella.

Aprende a usar caché distribuida como NCache en tu Aplicaciones EF Core para eliminar los cuellos de botella de escalabilidad de la base de datos.

Este seminario web cubrirá (incluidos ejemplos prácticos de fuentes):

  • Introducción a EF Core y sus nuevas funciones (Modelo, Consulta, Guardar datos)
  • Cuellos de botella en la escalabilidad de la base de datos en EF Core y cómo los resuelve la memoria caché distribuida
  • Varias opciones de uso NCache en EF Core (métodos Direct API y EF Core Extension)
  • Detalles del uso de los métodos de extensión de EF Core para el almacenamiento en caché
  • ¿Cómo manejar el almacenamiento en caché de colecciones y relaciones para referencia y datos transaccionales?
  • Algunas características importantes de un buen caché distribuido como NCache

EF Core es un motor de mapeo relacional de objetos para .NET y .NET Core aplicaciones Esto permite a los desarrolladores generar código de acceso a datos automáticamente, normalmente tendrían que escribir ese código ellos mismos. Similar a .NET CoreEF Core también es multiplataforma y me refiero a que puede ejecutarlo en Windows, Linux, Mac y se está volviendo muy popular entre la comunidad de desarrolladores.

En este seminario web, hablaremos sobre las necesidades de rendimiento y escalabilidad en las aplicaciones de EF Core y demostraremos diferentes estrategias para almacenar en caché datos transaccionales y de referencia mediante los métodos de extensión de EF Core. ¿Cuáles son los desafíos de rendimiento y escalabilidad que enfrentaría en una aplicación EF Core típica y luego hablaremos sobre varias opciones de uso del almacenamiento en caché dentro de las aplicaciones Entity Framework Core?

Me centraré principalmente en los métodos de extensión, los métodos de extensión EF que hemos implementado para las aplicaciones principales de Entity Framework. Por lo tanto, repasaré todos los métodos de extensión de Entity Framework Core de NCache y luego hablaremos sobre diferentes estrategias para manejar datos de referencia y datos transaccionales como sugirió Nick. También veremos cómo mantener los datos sincronizados cuando los datos existen en dos lugares diferentes cuando comienza a usar un caché distribuido. Entonces, eso es lo que tenemos en la agenda para el seminario web de hoy. Voy a empezar rápidamente. Tenemos mucho que cubrir. Hay muchos ejemplos prácticos que quiero mostrar. Entonces, comencemos rápidamente.

¿Qué es Entity Framework/EF Core?

Entonces, la primera diapositiva es más una introducción a Entity Framework y EF Core.

qué-es-entity-framework-core

EF y EF Core, este es un motor de mapeo relacional de objetos para .NET y .NET core aplicaciones La última versión de Entity Framework se llama EF Core. Ya sabes, recientemente hemos visto el lanzamiento de EF Core 2.1 junto con .NET Core 2.1. Ya sabes, simplifica la programación de tu base de datos. Ya sabes, te permite generar automáticamente tu modelo de acceso a datos. Entonces, no tienes que escribir eso tú mismo. Reduce el esfuerzo de desarrollo necesario para eso. No tiene que escribir código de persistencia que normalmente escribiría usted mismo en un nivel de ADO.NET y luego debe tener un mapeo entre su modelo de datos y el modelo de objetos. Entonces, simplemente optimiza eso para usted.

Entonces, es muy flexible. Se está volviendo muy popular dentro de la comunidad de desarrolladores y su multiplataforma y es muy popular en .NET y .NET Core Aplicaciones, específicamente aplicaciones altamente transaccionales que están lidiando con una gran cantidad de solicitudes.

Diagrama arquitectónico de Entity Framework

Este es un diagrama arquitectónico de Entity Framework.

diagrama de arquitectura

Ya sabes, también se aplica en EF Core. Hay pocas diferencias entre EF y EF Core. EF Core es liviano. Tiene enfoque modular. No hay muchos, no tiene que pasar por la instalación completa. Puede tener un enfoque modular. Lo han descompuesto en paquetes más pequeños, por lo que puede trabajar con el paquete que le interesa.

Por lo tanto, no tiene que pasar por una instalación completa y también se han deshecho de .edmx y esos archivos de mapeo. Entonces, ya sabes, los paquetes NuGet y hay algunos comandos que ejecutas y generan el modelo para ti y luego simplemente trabajas con LINQ to Entities API en la capa de la aplicación y el enfoque general sigue siendo el mismo.

¿Qué es la escalabilidad?

Por lo general, en una aplicación EF Core que conoce, hablaremos sobre los requisitos de rendimiento y escalabilidad. La escalabilidad es una capacidad dentro de una aplicación en la que puede aumentar la cantidad de solicitudes que esa aplicación tiene que manejar. Por ejemplo, su carga de usuarios crece o aquellos usuarios que contribuyen a la carga de solicitudes, esa carga de solicitudes crece dentro de una aplicación y si su aplicación se ralentiza, esa aplicación no es escalable.

Entonces, alto rendimiento bajo cargas máximas, eso es lo que categorizamos como escalabilidad. Si su aplicación funciona bastante bien, en una submilisegundo, con una latencia inferior a cinco usuarios, debería tener el mismo tipo de rendimiento, el mismo tipo de latencia, una latencia baja inferior a, digamos, cinco mil usuarios o quinientos mil usuarios y mucho de solicitud de carga.

Entonces, alto rendimiento bajo una carga de alto estrés, bajo cargas máximas, eso es lo que categorizamos como escalabilidad. Núcleo EF.

¿Cuáles son las aplicaciones que necesitan escalabilidad?

qué-aplicaciones-necesitan-escalabilidad

Podría ser una aplicación web ASP.NET. ASP.NET o ASP.NET Core que puede estar lidiando con muchas solicitudes. Podría ser .NET y .NET Core servicios web, nuevamente en el sitio web. Luego tenemos las aplicaciones de servidor IoT. De nuevo, podría ser .NET o .NET Core o cualquier otro .NET general y .NET Core Aplicaciones que pueden estar lidiando con muchas solicitudes o usuarios en sus propios dominios.

Entonces, esos son los candidatos para la escalabilidad.

¿Dónde está exactamente el problema de escalabilidad?

Por lo general, EF y EF Core se implementan en una granja web. Si es una aplicación web, se escalan linealmente. No tiene ningún problema de escalabilidad en el nivel de la aplicación, pero siempre tienen que hablar con una fuente de datos relacionales de back-end. Podría ser un servidor SQL. Podría ser Oracle Server o podría ser cualquier otro almacenamiento de datos compatible con EF o EF Core. En EF Core tienen muchos proveedores de datos. Hay una lista de proveedores entre los que puede elegir. Entonces, terminas hablando con una base de datos.

Aunque su nivel de aplicación se escala muy bien, este almacenamiento de datos, la base de datos, la base de datos relacional se convierte en una fuente de controversia. Es lento para comenzar porque no está en la memoria. Aunque EF Core ha creado un proveedor de datos en memoria, pero eso es un almacenamiento InProc y eso es para pruebas locales. Eso facilita sus pruebas, pero una vez que su aplicación se implementa en producción, debe lidiar con una base de datos relacional que es lenta y no se escala. Es muy bueno para el almacenamiento, pero no escala cuando realmente necesita esa escalabilidad dentro de su aplicación.

Por lo tanto, es una fuente única que puede ahogarse bajo cargas extremas.

La Solución

La solución es muy simple: comienza a usar un sistema de almacenamiento en caché perturbado como NCache, para su aplicación principal de EF, entonces la usa en combinación con una base de datos relacional.

Arquitectura de implementación

Aquí está la arquitectura de implementación de NCache.

arquitectura de implementación

En primer lugar, está en la memoria. Entonces, es súper rápido en comparación. Luego, tiene varios servidores que almacenan los datos que generalmente le permiten obtener de la fuente de datos relacionales de back-end. Puede traerlo al caché y podría ser su ASP.NET o ASP.NET Core Aplicaciones, .NET o .NET, servicios web o podría ser .NET o .NET Core Aplicaciones de servidor o cualquier tipo de .NET o .NET Core Las aplicaciones o incluso las aplicaciones Java pueden aprovechar este sistema de almacenamiento en caché distribuido. Le ahorra sus costosos viajes a las fuentes de datos relacionales. Está en la memoria. Puede agregar más servidores y aumentar la capacidad de este clúster de caché de forma lineal.

Por lo tanto, no es un único punto de falla. No es una actuación, cuello de botella. No es un cuello de botella de escalabilidad. Entonces, ese es el enfoque recomendado para ir con él y eso es lo que cubriremos con gran detalle hoy, cómo usar el almacenamiento en caché de .NET y eso será NCache como un producto de ejemplo en una aplicación EF Core a través de métodos de extensión.

3 casos de uso de almacenamiento en caché distribuido comúnmente utilizados

casos de uso de caché distribuida

Algunos casos de uso comunes de caché distribuida. Puede usarlo para el almacenamiento en caché de datos. Puede utilizar llamadas API directas. O use Entity Framework o Extension Methods incluso para EF Core Applications y guarde sus viajes a la base de datos tanto como sea posible.

Luego en el sitio web, el sitio web de las cosas, tienes ASP.NET, ASP.NET Core Almacenamiento en caché. Puede ser una aplicación web o un servicio web. Si se trata de una aplicación web, entonces si es posible que desee utilizar sesiones. Es posible que desee utilizar ASP.NET y ASP.NET Core SignalR Backplane, almacenamiento en caché de respuestas para un ASP.NET Core. Del mismo modo, la interfaz IDistributedCache está disponible, ver el estado y el almacenamiento en caché de salida. Todas estas son opciones sin código para sus aplicaciones.

Y luego tienes una potente mensajería Pub/Sub. Puede tener un tema al que se suscriba y luego compartir mensajes entre diferentes aplicaciones. Los editores y los suscriptores pueden enviarse mensajes entre sí.

Entonces, esa es una idea general. Nos centraremos más en el almacenamiento en caché de datos hoy dentro de una aplicación EF Core y lo guiaré a través de pasos simples para comenzar y luego expandiremos más, compartiendo más y más detalles en diferentes escenarios.

Entonces, comencemos rápidamente con esto.

Almacenamiento en caché de datos de aplicaciones: entidades principales de EF

Lo primero que me gustaría tratar hoy es el almacenamiento en caché de datos de aplicaciones.

qué-entidades-centrales-ef-almacenar-en-caché

Tiene entidades principales de EF. Por lo tanto, esas Entidades deben almacenarse en caché. Entonces, puede ver una sola entidad. Por ejemplo, tiene un conteo, suma. Ese es un valor o podría, está haciendo una clasificación y obtiene el primer cliente o el criterio es tal que está devolviendo un solo cliente, un solo producto, un solo pedido. Entonces, esa es una sola entidad, ¿cómo almacenarla en caché? Del mismo modo, tenemos resultados de consultas, podría ser una colección de entidades. Por lo tanto, no es una sola entidad. Es una colección de entidades. Hay dos opciones. Puede almacenar en caché toda la colección como un elemento en el caché o puede almacenar en caché cada elemento de la colección, cada entidad dentro de esa colección por separado en el caché distribuido.

Opciones de almacenamiento en caché de entidad central de EF

Entonces, repasemos los enfoques en torno a esto.

efcore-entity-caching-opciones

Como se discutió anteriormente, puede usar NCache APIs NCache La API es un almacén de valor clave, agrega datos a NCache usted mismo y luego lo recibe usted mismo o puede usar EF Core Extension Methods y hacerse cargo de esta entidad única y colección de entidades.

Entonces, primero déjame mostrarte el directo NCache Enfoque API que es común para todo tipo de aplicaciones. Puedes usarlo en EF Core. Puede usarlo en EF normal o en cualquier otra aplicación .NET y luego hablaré sobre los métodos de extensión de EF Core que están diseñados específicamente para sus aplicaciones principales de EF y esto hace que su vida sea mucho más fácil donde se hacen muchas cosas automáticamente. para usted y solo necesita llamar a este método de extensión junto con sus consultas. Entonces, les mostraré ambos enfoques uno por uno y luego nos enfocaremos más en los métodos de extensión en el futuro.

Almacenamiento en caché de una sola entidad de EF Core: NCache API directas

Por lo tanto, nuestro primer ejemplo es el almacenamiento en caché de una sola entidad de 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;
}
}

Tenemos un método GetCustomer, justo aquí. Te mostraré esto con la ayuda de una aplicación de muestra que he formulado para esto. Entonces, este es nuestro primer método. Espero que puedas ver mi pantalla. Entonces, tenemos Get Customer. Está tomando nuestra identificación de cliente y la idea aquí es que esto está devolviendo una sola entidad, ¿verdad? Por lo tanto, normalmente con la API directa, el desafío es que debe tener en cuenta algo que debe implementar usted mismo.

En primer lugar, debe tener una clave y esa clave es algo que identifica una entidad dentro NCache y necesita mantener todas las claves en el mismo formato. Puede crear un formato de muestra, como se muestra en la pantalla. Hay una palabra clave del cliente y luego la identificación del cliente y un parámetro de tiempo de ejecución de la identificación del cliente que hace la clave de caché.

In NCache todo se almacena en un par de valores clave. La clave es una clave de cadena y el valor es un objeto permitido de .NET y también podría ser cualquier entidad de EF Core, pero usted formula la clave y luego usa la entidad como un objeto para almacenarlo. NCache. Ahora primero verifica si esa clave ya existe en el caché o no llamando a caché. Obtener y si obtiene ese cliente directamente del caché y este es un directo NCache API cache.Get, pasa la clave y si obtiene ese cliente, devuelve el código desde aquí, si no es nulo. Pero, si es nulo, por ejemplo, está ejecutando esa consulta por primera vez, correcto, todavía no hay nada en el caché. Entonces, en ese caso, ejecutaría contra Entity Framework Core, la API de LINQ contra la base de datos y luego buscaría a ese cliente de la base de datos y también llamaría a la memoria caché. Insértelo, guárdelo con la misma clave que formuló y luego el cliente es el entidad que desea agregar y luego también la devuelve.

Entonces, así es como realmente trataría con una sola entidad usando la API correcta.

Almacenamiento en caché de la colección de entidades principales de EF: NCache API directas

Luego la colección. La colección podría ser una colección como un solo objeto o nuevamente como una sola entidad.

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 la colección podría ser una sola entidad agregada por separado en el caché. Entonces, para eso tenemos que obtener clientes por ciudad, entonces, ese es el siguiente método. Está devolviendo una lista de clientes. Nuevamente, está pasando la ciudad del cliente como criterio. De nuevo, formulas una clave. Nuevamente, esto es, ya sabes, esto representa una colección de clientes basada en la ciudad y luego esta ciudad podría ser un parámetro de tiempo de ejecución aquí. Nueva York, París, Londres y luego obtiene primero llamando a caché. Obtenga del caché usted mismo y luego verifique si existe en el caché, si lo hace, regresa desde aquí, si no, simplemente lo almacena como un colección única.

Entonces, esta lista de clientes se almacena como un objeto. Otra alternativa podría ser iterar a través de la lista de clientes individuales en entidades de clientes y caché de llamadas. Inserte individualmente como se muestra aquí. ¿Derecha? Entonces, entidades únicas y colecciones de entidades que usan directo NCache API como se almacenará en caché utilizando estos enfoques. Ahora hemos cubierto las API directas. Esto es algo que puedes usar en cualquier aplicación.

Almacenamiento en caché de una sola entidad de EF Core: métodos de extensión de EF Core

Centrémonos en los métodos de extensión del núcleo de Entity Framework. Entonces, lo mismo para una sola entidad y colección de entidades usando el NCache métodos de extensión. Entonces, voy a presentar 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;
}

Ese es nuestro primer método de extensión y, por cierto, para que se utilice este método de extensión, primero debe introducir NCache Paquete NuGet Entity Framework Core Paquete NuGet dentro de su aplicación. Entonces, eso es imprescindible. Si vas a instalado, este es un Alachisoft.NCachePaquete .EFCore NuGet. Eso es lo que necesita introducir dentro de su aplicación, ese es uno y luego todo lo que tiene que hacer es, permítame, simplemente abrir el contexto. Entonces, dentro del contexto simplemente llamas NCacheConfiguration.Configure y está tomando un ID de caché que estoy leyendo de la configuración de la aplicación y luego también está tomando el tipo de, si está usando dependencias, esa es una característica avanzada dentro de los métodos de extensión de Entity Framework Core. Debe proporcionar el tipo de fuente de datos.

Pero, una vez que hayas llamado NCache Configure el método, hay varias cosas que solicita este método. También puede configurar un registrador, pero eso es todo. Eso te permite empezar a llamar NCache, EF Core Extension Methods dentro de su aplicación.

Almacenamiento en caché de la colección de entidades de EF Core: métodos de extensión de EF Core

Entonces, el mismo método, pero esta vez obtenga clientes a través de métodos de extensión.

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;	
}

Va a hacer todo mucho más simple. No tiene que verificar los datos en el caché usted mismo y no tiene que llamar a insert explícitamente y, lo que es más importante, no tiene que llamar, no tiene que construir la clave del caché usted mismo. Esto está completamente automatizado como parte de la implementación de este 'FromCache'.

Ahora, desde el punto de vista del comportamiento, esto es exactamente lo que mostramos anteriormente. FromCache, en primer lugar, toma una opción de almacenamiento en caché, las opciones y 'cacheKey' es una referencia externa. Por lo tanto, construye la clave de caché automáticamente para usted detrás de escena. Solo necesita llamar desde el caché junto con su consulta como un método de extensión y simplemente pasa las opciones de almacenar eso si, siempre devuelve una colección, ¿verdad? Entonces, en ese caso, puede elegir que sea una entidad separada o una colección separada, ¿verdad? Entonces, podría ser una colección de entidades o podrían ser entidades separadas de esa colección.

Entonces, FromCache funciona de tal manera que si una entidad o si una consulta que ejecutó y esas entidades resultantes ya están en el caché, las obtendrá de NCache automáticamente. Pero, si no están en el caché en ese caso, ejecutaría automáticamente esa consulta en la base de datos y se devuelve el conjunto de resultados y, al mismo tiempo, también se almacena en caché y también adjuntamos el contexto de la base de datos para llamadas posteriores.

Por ejemplo, si llama a FromCache por primera vez, lo almacena en caché. La próxima vez que se ejecute la misma consulta, obviamente se ejecutará en el caché pero no en la base de datos. Esta vez su contexto, si se eliminó anteriormente y para esta solicitud estaba utilizando la construcción de uso para el caso, si realiza algún cambio en las entidades que también adjuntan esos cambios al contexto. Y cuando llama a Guardar cambios, todos los cambios que se realizaron en esas entidades que se recuperaron del caché se aplican realmente en la base de datos. Entonces, eso es un poco, nuevamente un concepto un poco avanzado. Pasaré un poco más de tiempo, en una etapa posterior, pero solo para hacerle saber, el método de caché funciona de tal manera que si algo no está en el caché, lo obtendrá de la base de datos y lo almacenará en caché. Pero, si algo ya está disponible en el caché, simplemente lo devolverá desde allí. Entonces, esto automatiza todo el enfoque directo de la API para usted, pero también construye las claves. También organiza los datos en una entidad separada o una colección separada automáticamente y solo tiene que llamar desde el caché y pasar la clave de salida y las opciones.

Mismo caso para las colecciones. Para una colección, obtener cliente por ciudad. Se almacenaría como una colección y luego nuevamente puede llamar desde el caché. Entonces, así de simple es comenzar con los métodos de extensión de Entity Framework Core.

¿Qué datos almacenar en caché en EF Core?

Nuestro próximo tema es sobre, nuestro próximo tema es nuevamente sobre el uso del tipo de datos en el caché.

qué-datos-caché-en-efcore

Puede tener datos de referencia o datos transaccionales. ¿Hay alguna pregunta?

Sí, Ron, tengo una pregunta aquí. Métodos de extensión de NCache trabajar con EF Core, usted recomienda .NET Core 2.0 Framework o un .NET Framework?

Bien. Entonces, dado que EF Core puede ejecutarse tanto en .NET como en .NET Core, entonces, es muy flexible. NCache los métodos de extensión funcionarían absolutamente bien. De hecho, estoy ejecutando esta aplicación de muestra en .NET framework 4.6.1 y tengo otra aplicación de muestra que está funcionando, creo .NET core 2.0. Entonces esto es .NET Core 2.0. Por lo tanto, funciona con ambos .NET frameworks y básicamente es preferible que uses .NET Core, pero es flexible. Funcionará para ambos. Espero haber respondido a tu pregunta.

Continuando, el siguiente segmento dentro de la presentación es cuando comienza a planificar el almacenamiento en caché correctamente y, obviamente, los métodos de extensión del núcleo del marco de entidad hacen que su vida sea mucho más fácil en términos de almacenamiento en caché. Entonces, en realidad hace muchas cosas automáticamente. Entonces, la siguiente pregunta es qué datos almacenar en caché, ¿verdad?

Por lo tanto, he clasificado los datos en dos categorías. Disponemos de datos de referencia. Eso es una búsqueda de datos y luego tenemos nuestros datos transaccionales, que se crean dinámicamente y cambian con mucha frecuencia. Entonces, datos de referencia, un ejemplo rápido serían productos, empleados. No es un dato 100% estático, pero es algo que no cambia con tanta frecuencia. Pero cambia, la frecuencia de cambio no es tan grande. Y para esto, debe planear almacenar en caché todos los datos de referencia. Todos los datos de referencia deben almacenarse en caché como una necesidad y luego los datos transaccionales son datos creados dinámicamente. Como pedidos, cuentas, algún procesamiento de flujo de trabajo en alguna colección específica de datos y el alcance de esa colección es solo para ese flujo de trabajo. Una vez que ese flujo de trabajo completa la ejecución, esos datos ya no son necesarios y estos datos también pueden cambiar con mucha frecuencia. Tanto es así, que puede cambiar en cinco minutos. Mientras que los datos de referencia suelen ser datos de búsqueda que pueden cambiar entre horas. 1 a 2 horas, 5 a 10 horas o incluso en días.

Tenemos una pregunta aquí. ¿Cómo identificaría este objeto almacenado en caché cuando lo recupera usando EF Extensions como claves creadas automáticamente? En realidad, ¿no recuperar sino eliminar una clave en particular?

Bien. Por lo tanto, tenemos un método de extensión para la recuperación. El método de extensión se ejecuta junto con EF Core. Por lo tanto, el objeto de retorno se identificaría en las mismas líneas que su consulta LINQ lo identificaría. Creo que la pregunta se centra más en lo que sucede cuando planea actualizar los registros y para eso tenemos un conjunto de API. Le damos un método que le permite generar una clave contra una entidad. Hay un método de generación de claves que hicimos público. Entonces, antes de hacer un cambio en el caché directamente, supongo que esta pregunta se enfoca más en eliminar algo en el caché o actualizar algo en el caché o eliminar o agregar algo en el caché explícitamente. Hemos expuesto la clase de caché que les mostraré en un momento y luego hay una generación de claves. Nuevamente, pasa una cadena y usa la referencia de salida y también pasa la entidad. Entonces, contra esa entidad usamos el mismo enfoque y le daremos una clave y usando esa clave puede identificar el objeto de esa entidad, si existe en el caché, debería poder actualizarlo y eliminarlo.

Creo que hacia el final les mostraré un ejemplo de cómo lograrlo, pero solo para hacerles saber, hay métodos a los que nos expusieron, sacar la llave de NCache así como. Espero que responda a su pregunta.

Almacenamiento en caché de datos de referencia en EF Core

Hacia adelante. Entonces, hemos hablado sobre datos de búsqueda y luego datos creados dinámicamente.

caché-datos-de-referencia-en-ef-core

Entonces, revisaré uno por uno, diferentes enfoques para manejar esto. Entonces, antes que nada, hablaremos sobre los datos de referencia en EF Core. Como mencioné, esto suele ser una búsqueda de datos. Por lo tanto, hay dos cosas que debe hacer como un deber. En primer lugar, debe cargar datos completos, datos de referencia completos en el caché como una necesidad y la motivación aquí es que estos datos son algo que no cambia con tanta frecuencia. Es un catálogo de productos en un EF, en una aplicación de comercio electrónico. Hay algunos descuentos en ciertos productos mientras ese descuento está habilitado, digamos durante tres días. Es posible que esos productos no cambien, por lo que es mejor almacenar en caché todos esos productos en NCache y ahorre sus costosos viajes a la base de datos para hacer eso tanto como sea posible. 100%, los datos deben cargarse en el caché. Por lo tanto, no tiene que volver a la fuente de datos y luego almacenarlos siempre en caché como entidades separadas. ¿Por qué? Porque los productos, todo el conjunto de datos podría ser miles y miles de productos.

Digamos, la base de datos Northwind. Los productos pueden oscilar entre 50,000 y 100,000 productos. Pero, es posible que solo necesite, digamos, 10 de esos o 100 de esos para una solicitud determinada. Entonces, si los almacena como entidades separadas, puede ejecutar consultas LINQ. NCache también es compatible con LINQ en NCache directamente. Por lo tanto, puede ejecutar LINQ para obtener el subconjunto de los datos consultando el subconjunto de las entidades de NCache .

Entonces, estas son dos reglas que debe seguir como un deber y tengo un ejemplo y aquí estoy introduciendo nuestro segundo método de extensión que se llama Cargar en el caché.

Almacenamiento en caché de datos de referencia en EF Core: caché de carga previa

Ahora, esto funciona de tal manera y está destinado solo a datos de referencia. Este es un precargador en el caché.

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();
}

Entonces, la motivación aquí es que debe llamar a este método, digamos Cargar todos los productos y debe asegurarse de almacenarlo como entidades separadas y debe ejecutar una consulta que dice de productos en la base de datos productos y seleccionar productos . Entonces, no está especificando ningún criterio que signifique que esto cargaría los 60,000 productos en el caché y luego está usando LoadIntoCache, ¿verdad? Cuando dice entidades separadas, solo necesita pasar esta opción y crearemos una entidad separada para cada producto en el caché y esto es nuevamente un precargador, correcto. Deberías precargar esto...

Hay dos opciones. Puede ejecutar una aplicación separada para esto que puede asumir la responsabilidad de precargar el caché. Esto podría ser el inicio de la aplicación o una aplicación separada o podría ser una implementación del cargador de caché de NCache así como. Hay un cargador de caché y, en futuras versiones, también trabajaremos en la actualización de caché.

La responsabilidad del cargador de caché es que en realidad se ejecuta al inicio de su caché y luego se asegura de que todos los datos que desea cargar en el caché se carguen como parte de eso. Es su implementación pero NCache simplemente lo llama. Pero, como mencioné, puede crear un método como este y asegurarse de llamarlo una vez al inicio de la aplicación o hacer que una aplicación separada haga esto y comparta estos datos en todas las instancias de su aplicación.

Ahora, una vez hecho esto, cómo consultar datos fuera del caché y en ese punto. Voy a presentar mi tercer método de extensión, que es solo desde caché.

Almacenamiento en caché de datos de referencia en EF Core: buscar datos de referencia solo en caché
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;

}

Entonces, el primer método de extensión fue FromCache, que era, si algo está en el caché, obténgalo desde allí. Si no es así, vaya automáticamente a la base de datos y búsquelo. LoadIntoCache siempre se ejecuta contra la base de datos. Nunca se ejecuta contra el caché aunque está regresando, pero esto está regresando de la base de datos como una necesidad para que el conjunto de datos se actualice. Se cargan nuevos datos y luego también se almacenan en caché, y luego FromCacheOnly solo se ejecuta contra NCache porque esto está diseñado solo para los datos de referencia. Entonces, para datos de referencia, usaría una combinación de LoadIntoCache. Entonces, todos los datos del conjunto de datos existen en el caché como entidades separadas y luego llamará a FromCacheOnly para que solo el conjunto de datos que le interese, es decir, los productos descontinuados en este caso, se hayan traído solo del caché. Por lo tanto, no tiene que ir a la base de datos en absoluto. Hablaré sobre cómo mantener estos datos actualizados cuando los datos cambien en la base de datos. Entonces, espero que esto tenga sentido. Déjame mostrarte este ejemplo aquí mismo.

Entonces, llamo a este método aquí y luego devuelvo una lista de productos, productos descontinuados usando un EF simple, la API de LINQ directamente en NCache entidades.

Entonces, esto no se ejecutaría contra la base de datos en absoluto. Esto se ejecutaría solo contra el caché porque estoy usando FromCacheOnly, método de extensión. Espero que esto ayude. Hemos cubierto tres métodos de extensión, FromCache, que es más un caso de uso de datos transaccionales y luego cubrimos LoadIntoCache y FromCacheOnly. Para datos de referencia, debe enfocarse en usar datos completos usando LoadIntoCache y luego separar entidades y luego para consultas debe usar FromCacheOnly.

Almacenamiento en caché de datos transaccionales en EF Core

A continuación, hablaremos sobre los datos transaccionales y luego hablaremos sobre cómo mantener estos datos actualizados tanto para referencia como transaccionales.

almacenamiento en caché de datos transaccionales en efcore

Ahora, los datos transaccionales suelen ser un conjunto de trabajo. Ya he cubierto que es un dato creado dinámicamente. Solo es necesario para un usuario actual, una solicitud actual o un flujo de trabajo que se está ejecutando y, una vez que se ejecuta, es posible que ya no necesite esos datos. Por lo tanto, es probable que solo la instancia de la aplicación que realmente recupere esos datos que esas entidades solo sean necesarias para esa instancia de la aplicación. Por lo tanto, no tiene sentido almacenar todos sus datos transaccionales en el caché. No es un requisito. Solo debe almacenar en caché el conjunto de trabajo. Entonces, ese es el paso número uno. Por lo tanto, debe almacenar en caché los resultados de la consulta. Puede buscar entidades de acceso más fácil y el segundo paso es que hay dos opciones 2a, 2b.

Obtener y almacenar en caché como colección

Puede almacenar en caché sus datos transaccionales como una colección completa. Ese es un enfoque preferido.

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;
}

Por lo general, siempre necesita la colección completa, porque está trabajando en ella y luego también puede almacenar, entidades separadas también. Depende totalmente de usted y esto es para el escenario en el que, aunque almacenó en caché una colección, aún la almacena como entidades separadas porque es posible que solo necesite dos o tres entidades de esa colección. Por lo tanto, es mejor tener un enfoque granular al almacenar las colecciones y tenemos GetCustomerOrders. Los pedidos son datos bastante transaccionales. Debe haber una unidad de procesamiento que se ocupe de ciertos pedidos y lo más probable es que cada flujo de trabajo que lo hace tenga su propio conjunto de pedidos.

Entonces, les mostraré este ejemplo muy rápido. Entonces, está funcionando de tal manera que está poniendo muchas opciones de almacenamiento en caché. No entremos en detalles aquí. Almacenar como colección. Así es como elige almacenarlo como una colección y luego estoy usando FromCacheOnly. El motivo de los datos transaccionales es que estoy usando FromCache porque los datos pueden existir en la memoria caché y, si se trata de toda la colección, solo necesito usarlos. No tengo que ir a la base de datos. Pero, si no existe en el caché y estos datos también cambian con mucha frecuencia, también hemos configurado una caducidad, digamos, 30 segundos, por lo que es posible que desee volver a la base de datos. Si usa FromCacheOnly, puede devolver un valor nulo si no existe en el caché, si ya ha caducado.

Por lo tanto, para datos transaccionales use el método de extensión From Cache, para datos de referencia use LoadIntoCache para precargar y luego use FromCacheOnly. Entonces, ese es el enfoque para hacerlo.

Recuperar y almacenar en caché como entidades separadas

Para entidades separadas, todo lo que tiene que hacer es almacenar, llame a esto.

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;
}

Permítanme usar esto y, en lugar de usar una entidad separada, solo digan (tengo que comentar, debería haber comentado) Correcto, almacenar como Entidades separadas. Eso es todo lo que necesitas hacer.

Entonces, Ron, mientras revisas esto, hay una pregunta. En el ejemplo anterior, consultando datos de referencia, ¿hay alguna indexación? Porque, solo eso es lo que harías en la base de datos para hacerlo….

Absolutamente, esa es una muy buena pregunta y para datos de referencia, dado que se ejecuta solo en caché, esta consulta LINQ requiere que su producto y el atributo estén indexados a lo largo del cual está ejecutando la consulta LINQ y, de hecho, estoy utilizando datos de índice y es muy simple de indexar, solo necesita proporcionar el tipo, el modelo y luego proporcionar los atributos que necesita indexar. Entonces, estos son atributos de índice y, de hecho, estamos ejecutando consultas contra atributos de índice. Espero haber respondido a tu pregunta.

Mantener el caché actualizado

Pasaré a nuestra parte práctica muy rápido, le mostraré el producto real en acción y luego el segmento más importante de este seminario web: cómo mantener actualizados los datos de caché en comparación con la base de datos y también con respecto a los datos de referencia y datos transaccionales.

Muy bien, entonces voy a abrir un nuevo proyecto. Muy bien, entonces, en la parte de demostración práctica, le mostraré rápidamente el producto real en acción para que sepa cómo se ve un almacenamiento en caché distribuido y luego ejecutaremos la aplicación contra él y le mostraré cómo mantener fresco, los datos y el caché como nuevos.

Ya he instalado NCache en dos de mis cajas 107 y 108. Los voy a usar como mis servidores de caché y mi máquina personal aquí, mi computadora portátil va a actuar como un cliente.

Entonces, antes que nada, lanzaré el NCache herramienta de administrador que viene instalada con NCache y crearé un caché, digamos, llamémoslo EF Core cache. Usaré dos servidores. Mantenga las réplicas de partición como nuestra topología de almacenamiento en caché y luego la opción de replicación asíncrona porque es más rápida y aquí especifiqué los servidores que alojarán mi caché. Entonces, tengo dos servidores, demo 1 y demo 2 y puerto TCP/IP para comunicación. Todo está impulsado por TCP/IP en lo que respecta a la comunicación entre servidores y clientes.

Tamaño de la memoria caché, en función de los datos que planea almacenar en la memoria caché. Si son datos de referencia debes tener en cuenta que estás cargando todos los productos, todos los clientes. Del mismo modo, si se trata de datos transaccionales, debe tener en cuenta el conjunto de trabajo y también un poco más de espacio para eso. Mantén todo simple, elige acabado y listo. Así de sencillo es empezar con NCache y configurar un caché.

Dado que estoy ejecutando aplicaciones en mi máquina, solo necesito agregar mi caja como una máquina cliente. Puedo iniciar y probar este clúster de caché y luego estoy listo para ejecutar la aplicación de muestra para conectarme a él. Así de simple es. tenemos un regular NCache Seminario web sobre arquitectura y escalado de aplicaciones .NET en el que hablamos sobre estas configuraciones con gran detalle. Por lo tanto, si tiene alguna pregunta, es posible que también desee consultar esos seminarios web.

También le mostraré algunos aspectos de monitoreo. Ventana de estadísticas y luego abriré NCache herramienta de monitoreo para que pueda ejecutar la aplicación de la herramienta de prueba de estrés que viene instalada con NCache y ver las cosas en acción. Entonces, esta es una herramienta de prueba de estrés. Lo ejecutaré contra esto porque mi caja es un cliente, así que simplemente puedo proporcionar el nombre y debería conectarse a esto y debería poder simular una carga ficticia en mi clúster de caché, ahí lo tienes. El tamaño de la memoria caché está creciendo, se están agregando elementos y las solicitudes por segundo de carga también muestran actividad en ambos servidores y luego esta herramienta de monitoreo, creo que está tomando tiempo, está creando un tablero.

herramienta de prueba de estrés

Entonces, déjelo funcionar y, mientras tanto, permítame ejecutar otra instancia de esta herramienta desde el propio servidor. Culpa mía. Muy bien, puede ver cómo aumenta la cantidad de solicitudes por segundo. Por alguna razón está tardando un poco en cargar el tablero, la herramienta de monitoreo. Creo que lo dejaré aquí mismo, tan pronto como vuelva, les mostraré los detalles de monitoreo de esta herramienta.

Mantener la memoria caché actualizada: datos de referencia

Muy bien, nuestro próximo segmento dentro de este seminario web es mantener actualizados los datos de caché dentro de una aplicación Entity Framework Core y para esto volveré a usar datos de referencia y ejemplos de datos transaccionales. Entonces, comenzaremos con datos de referencia.

mantener-caché-fresco-datos-de-referencia

Ya hemos establecido que para almacenar en caché los datos de referencia, debe almacenar en caché todo el conjunto de datos en el caché. Por ejemplo, tiene productos, debe cargar todos los productos en el caché y luego cargarlos como entidades separadas. Entonces, ¿cuál es el problema con esto?

Dado que, los datos de referencia, todos los datos de referencia en el caché y luego solo usa el caché usando el método de extensión FromCacheOnly. Ahora, no desea permitirse un conjunto de datos parciales fuera del caché. Si se trata de productos descontinuados o está ejecutando algunos criterios, desea que todos esos productos estén en el caché. Pero, hay posibilidades de que esos productos realmente cambien en la base de datos. Ahora los datos existen en dos lugares diferentes. Tiene una base de datos que es su copia maestra y aunque cargó datos completos en el caché, todavía hay posibilidades de que la base de datos se actualice fuera del alcance de sus aplicaciones.

Entonces, para mantener actualizados los datos de la memoria caché, debe asegurarse de tener algún tipo de mecanismo que actualice los datos y la memoria caché automáticamente y para eso tenemos dos opciones. La opción número uno es que utilice la caducidad.

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();

}

Este es un vencimiento basado en el tiempo y luego lo mezcla, lo usa además con la función de recarga automática. NCache La función de caducidad le permite caducar datos, eliminar datos después del período de tiempo especificado, digamos, 5 horas, 10 horas y con datos de referencia, ya que son datos de larga ejecución, son datos de búsqueda, datos maestros, por lo que la frecuencia de cambio no es así de genial, para que puedas pensar en un número cómodo de ya sabes, horas o ya sabes, podría ser 5 horas, 10 horas, 24 horas. Entonces, en base a eso, puede configurar un tiempo de vencimiento. Pero, como se mencionó anteriormente, realmente no desea perder o eliminar esos datos del caché.

Lo que realmente necesita es que los datos que se modifican, digamos, 10 productos caducan en función de la caducidad de lo que especificó, debería volver a cargar automáticamente esos datos en el caché con un mecanismo de recarga automática. Y NCache le proporciona eso con la ayuda de un controlador de lectura. Por lo tanto, todo lo que tiene que hacer es volver a cargar los datos completos y la memoria caché usando la carga en la memoria caché, usar entidades separadas pero junto con eso, usar estas características. Por ejemplo, Establecer caducidad absoluta.

Ese es el valor de caducidad que establecería para todos los productos que se cargarán en el caché y luego establecerá el proveedor de resincronización, que esencialmente llama a su proveedor de lectura dentro NCache. La lectura completa se combina con la caducidad. Entonces, en lugar de eliminar datos del caché, en realidad se recarga, ya que conoce todas las claves y toda la información relacionada con la base de datos, solo necesitamos que pase el contexto y, en función de ese contexto, llamamos a su proveedor automáticamente y resincronizamos. Obtenemos el valor actualizado de la fuente de datos.

Déjame mostrarte un ejemplo práctico de ello. Aquí hay un método. Estoy almacenando esto como entidades separadas. Por lo general, establecería una caducidad de 5 horas, pero dado que no tenemos tanto tiempo, lo que realmente haría es establecer una caducidad de unos 30 segundos y colocaré un punto de interrupción aquí y cargaré todos los productos en el caché. No configuraría un proveedor de resincronización en este punto solo para mostrarle cómo funcionan los vencimientos y, tan pronto como el vencimiento entre en juego, eliminará los elementos del caché y luego le mostraré cómo solucionar este escenario. de tal manera que en lugar de eliminar, simplemente vuelva a cargar usando el controlador de lectura.

Entonces, usaré el caché local para este bit de muestra. Borraré el contenido solo para estar seguro y luego ejecutaré este fragmento de código y llegaré al punto de interrupción. Derecha. Entonces, tiene 30 segundos de caducidad y simplemente presionaré y obtuve los productos descontinuados, ¿verdad? Entonces, tenemos todos los productos aquí y tenemos alrededor de mil entradas aquí. Después de 30 segundos, estos mil elementos caducan en función de esta caducidad absoluta, marque que hemos configurado y ejecutaré esta consulta nuevamente y verá que no devolverá nada porque no existe nada en el caché. Está usando solo desde caché. Entonces, tenemos artículos caducados. Ejecutaré esto una vez más y notarán que obtuve 0 valores.

Por lo tanto, esto no es lo que se recomienda o lo que se prefiere, considerando que estos son sus datos de referencia, los datos completos ya están cargados en el caché y está llamando al método de extensión From Cache Only. Por lo tanto, necesita todos los datos disponibles como una necesidad, no la respuesta parcial o los datos faltantes y, al mismo tiempo, esto debe volver a cargarse después de su vencimiento. En lugar de eliminarlo, debe volver a cargar y eso es exactamente lo que haremos con la ayuda de este nombre de proveedor de configuración de resincronización.

Tengo un proveedor de resincronización de muestra, que está justo aquí, IReadThruProvider. Lo que realmente hace es que le hemos dado una implementación predeterminada de esto.

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 es nuestro IReadThruProvider. Todo lo que tiene que hacer es mostrar esto con la ayuda del caché que hemos configurado. Tienes que configurar el controlador de lectura. Por ejemplo, déjame crear un nuevo caché, déjame crear un caché local. Derecha. Entonces, es solo un caché local. Voy a configurar una fuente de respaldo. Habilite la lectura completa, agregue y digamos EF predeterminado y esto debe configurarse y puedo usarlo como un proyecto y la implementación ya está hecha.

Funciona de tal manera que implementé el controlador IReadThru. Este es el proveedor de resincronización predeterminado, a la derecha. Tiene algunos métodos. Tiene inicialización donde inicializa el contexto DB. LoadFromSource, que se llama al vencimiento y dentro de esto obtengo el elemento de la base de datos. Si entro en la definición, en realidad se ocupa de todas las llamadas relacionadas con la base de datos y esto es algo que estamos proporcionando como parte de nuestra implementación. Nuestro paquete NuGet lo cubre como parte de él. Entonces, estamos obteniendo la clave y, en función de esa clave, pasa el contexto y el contexto se usa para obtener el objeto real directamente de la base de datos.

Todo lo que tiene que hacer es heredar, implementar este proveedor de resincronización predeterminado de EF y brindar su propia implementación y brindarnos el contexto de la base de datos.

Entonces, esta es una clase abstracta que les hemos dado. Solo necesita proporcionar el contexto de su base de datos Northwind o cualquier contexto de base de datos que tenga y, en base a eso, una vez que este método se anule / implemente, simplemente registre esto con su caché. Por ejemplo, este es un proveedor de resincronización. Si abro esto, contiene dos de esos. Uno es predeterminado y el otro es su implementación y puede pasar su cadena de conexión y otra información si es necesario y eso es todo. Simplemente implementa esto. Permítame llevarlo a este punto y le daría un éxito en esto. Entonces, eso tiene que hacerse. Como mencioné, esto ya se hace como parte de NCache, implementación. Tiene, el paquete NuGet viene con un proveedor de resincronización que puede implementar simplemente implementando este método particular aquí y brindándonos el contexto y el resto del trabajo lo realiza este proveedor de resincronización predeterminado de muestra, que en realidad funciona en las mismas líneas que la extensión los métodos funcionan.

Construimos su clave, por lo que sabemos qué clave representa qué entidad y, en función de esa entidad y esa información clave, consultamos la base de datos utilizando Entity Framework, API. Ahora bien, esto ya se ha hecho para mi caché. Lo que he hecho aquí es que lo he implementado con éxito. Entonces, para mi caché ya hice esto. Tengo este valor predeterminado de EF y lo he implementado. Entonces, ejecutaré el mismo caso de uso, pero esta vez, en lugar de simplemente expirarlo, en realidad lo volvería a cargar. Entonces, eso es lo que voy a hacer. Todo lo que tengo que hacer es configurar su nombre de proveedor de resincronización y, dado que también planeo actualizar algunos valores, usaré 60 segundos. Por lo general, para los datos de referencia, tendría mucho más tiempo especificado como vencimiento absoluto, como 5 horas o incluso más. Entonces, solo lo ejecutaré con 60 segundos y esta vez veo que mi proveedor de resincronización está configurado.

Entonces, ejecutaré este caso de uso una vez más y le mostraré cómo se actualiza en lugar de caducar, en lugar de eliminarlo. Entonces, esto se ha ejecutado y, con suerte, volverá a este punto. Bien. Entonces, tenemos productos cargados. Ejecutaré esto una vez más y, en este momento, dado que tiene 60 segundos de vencimiento, actualizaré este producto en particular, ID de producto 17 y lo que haremos es simplemente actualizarlo, está bien.

Aunque está actualizado en la base de datos, todavía no se actualizará en el contexto de la aplicación, porque solo usa datos de caché y aún no ha caducado. Por lo tanto, seguiremos obteniendo los valores anteriores y, si nota que en mi caché tenemos miles de elementos y hay una lectura por segundo, esto mostraría algo de actividad después de 60 segundos y luego llamaría automáticamente al controlador de lectura que tenemos. solo configura

Entonces, permítanme ejecutarlo una vez más y estoy esperando valores de pedido nuevamente, si aún no se ha recargado, pero habría un punto en el que simplemente se recargaría y luego simplemente, en lugar de caducar, recargaría el 999 de los productos. Hay un elemento que es extra, que suele ser una referencia. Ahí tienes Entonces, en lugar de caducar, solo caducó un elemento porque es una lista de claves, de lo contrario, todos los datos de referencia se basan en mi consulta, déjame mostrarte la consulta, dice dónde la identificación del producto es inferior a 1000. Entonces, eso en realidad representa 1000 productos.

Por lo tanto, ejecutaré esta consulta una vez más y esta vez dado que los datos ya se actualizaron al vencimiento, en lugar de eliminarlos. Entonces, espero que el producto actualizado se agregue en el caché. Ahí vas. Entonces, mi producto ha sido actualizado como parte de esto. Entonces, esto es lo que recomendamos como parte de nuestra opción número uno, dijo que usa la caducidad pero con la función de recarga automática. Entonces, en lugar de caducar, simplemente recarga los datos y esto se encargará de mantener actualizados los datos de la memoria caché. Por lo tanto, encuentra un tiempo cómodo que le permite mantener los datos en el caché, sigue obteniendo datos más antiguos y, tan pronto como esos datos más antiguos estén a punto de caducar, eso podría ser un día de tiempo, digamos, 24 horas. , podría ser 2 días, a la semana, el tiempo que sea cómodo dentro de su aplicación. También podrían ser algunas horas y después de eso, simplemente volvería a cargar esos datos en el caché.

Entonces, esa es nuestra opción número uno. Espero que haya sido bastante sencillo.

La opción número dos es que no utilice un vencimiento. Entonces, eso solo resolvería este problema aquí donde los datos siempre existirían en el caché. Pero los datos pueden quedar obsoletos en la memoria caché y podrían quedar obsoletos para siempre. Para eso, debes recargar manualmente y eso también es muy simple.

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

}

Todo lo que tiene que hacer es llamar a Cargar todos los productos después de un intervalo periódico. Por ejemplo, si volvemos a este bit aquí mismo. Por lo tanto, es necesario llamar a este método después de algunos intervalos y, nuevamente, como se mencionó anteriormente, esto generalmente se hace al inicio de la aplicación y podría ser una de las aplicaciones que se está encargando de todo esto. Entonces, podría ser eso o podría ser una de las aplicaciones, una aplicación separada que está haciendo eso. Por lo tanto, podría ser su aplicación, una de sus instancias de aplicación o podría ser una aplicación separada por completo y esa aplicación puede llamar periódicamente a este método después de, digamos, 5 horas, 24 horas, nuevamente, que es su tiempo cómodo después del cual desea esto se ejecutará contra la base de datos y desea que sus productos se vuelvan a cargar.

Por lo tanto, LoadIntoCache se encargaría de ese escenario particular en el que se ejecutaría contra la base de datos y cargaría copias nuevas en el caché. Entonces, así es como te haces cargo de los datos de referencia. Espero haber sido bastante directo.

Mantenga la memoria caché actualizada: datos transaccionales

Pasemos al siguiente segmento donde usamos datos transaccionales. Ahora los datos transaccionales son algo de corta duración, ¿verdad? Es un conjunto de trabajo, como se explicó anteriormente. Entonces, puede usar de 5 a 10 minutos de vencimiento. Entonces, lo que realmente necesita hacer aquí, ya que está usando FromCache que se ejecuta contra el caché, si existe en el caché y si no existe en el caché, siempre se ejecutará contra la base de datos automáticamente. Entonces, esto está integrado en este método de extensión, a diferencia de FromCacheOnly, que usa con el escenario de datos de referencia, correcto, que solo se ejecuta contra el caché. Por lo tanto, está bien tener algunos datos disponibles, ya sea que los haya almacenado como una colección o como una entidad separada.

Caducidad corta, sin 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;
 }

Entonces, simplemente usa un vencimiento corto, digamos 60 segundos, aunque usé ese ejemplo para datos de referencia pero eso fue por el bien de esta demostración en particular, pero para datos de referencia generalmente tiene de 5 a 10 horas de vencimiento y para datos transaccionales tiene en algún lugar entre 60 segundos o relacionado, caducidad adjunta y dado que está usando From Cache, echemos un vistazo a Obtener pedidos de clientes, ya que está usando FromCache que debería permitirle usar el, tomemos esto como ejemplo.

Correcto, entonces, configura un vencimiento aquí y llama a este método de extensión FromCache y eso debería encargarse de obtenerlo de la base de datos si no existe en el caché y después de un tiempo si su conjunto de trabajo está activo en el caché lo obtendría del caché, si no está activo en el caché, es probable que ya no sea necesario, ¿verdad? Entonces, puede terminar volviendo a la base de datos y eso es lo correcto con los datos transaccionales. Entonces, espero que esto cubra nuestros datos de referencia, así como los escenarios de datos transaccionales y cómo mantener actualizados los datos de caché con respecto a estos dos.

Manejo de relaciones en caché

Pasaré al siguiente segmento, que es Manejo de relaciones en caché.

Ron, tengo un par de preguntas aquí. ¿El NCache o los elementos almacenados en caché residen en el NCache servidor o están sombreados en cada servidor de aplicaciones?

ellos residen en NCache. Correcto, entonces los elementos realmente existen en NCache, derecho. Por lo tanto, el repositorio real se mantiene dentro de NCache y en realidad construimos las claves y los objetos junto con estos métodos de entidad. Entonces, esa es la idea aquí.

Otra pregunta es, ¿podemos tener varios cargadores de caché configurados o todos deben configurarse en uno, cuando estábamos agregando datos de referencia al caché?

Puede porque cargar en caché es un método genérico, ¿verdad? Entonces, en realidad carga lo que sea, la consulta que planea ejecutar correctamente. Por lo tanto, está vinculado a la consulta. Puede tener un múltiplo de carga en caché y podría haber una aplicación separada o podría haber diferentes lugares dentro de la aplicación. Entonces, también es muy flexible en ese sentido.

Manejo de relaciones en caché: uno-muchos

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;
}

Hay algunos conceptos importantes que quiero resaltar. ¿Cómo manejar las relaciones? Ejemplo de uno a muchos y ya sabes, de muchos a muchos.

Centrémonos en uno a muchos. Si tiene regiones, digamos, y luego hay territorios que forman parte de regiones y existe una relación de uno a muchos entre regiones y territorios. Vayamos al enfoque de sincronización y, en realidad, obtengamos las regiones desde aquí.

Muy bien, obtenga regiones con territorios. La idea básica aquí es que tiene la palabra clave Incluir y luego usa FromCache y siempre la almacena como una entidad separada. La idea aquí es que el elemento principal de la región se almacenará como un elemento separado en el caché. Dado que la región también tiene una relación de uno a muchos con los territorios y hay una colección de territorios dentro de cada entidad de región, entonces, NCache obedecería eso. Tan pronto como llame a FromCache, simplemente obtendrá la región y todas las regiones se almacenarán como entidades separadas y, según el alcance que especifique, todos los territorios con la ayuda de FromCache se almacenarán como una colección separada dentro de cada región. .

Entonces, es una entidad que tiene muchos lados, el lado de la colección como un objeto relacionado. Entonces, así es como aborda el caso de uso de uno a muchos.

Almacenamiento en caché de operaciones agregadas

Luego tienes las operaciones agregadas de almacenamiento en caché. Ya sabes, puedes dar como resultado una entidad o dar como resultado un valor.

almacenamiento en caché de operaciones agregadas

Por ejemplo, obtener un remitente Primero o Predeterminado, correcto. Entonces, eso es algo, digamos, si solo hago Primero o Predeterminado aquí, esto me buscaría el primer remitente y luego, en base a esto, esto se almacenará en NCache.

Y de manera similar, podría ser una suma de conteo. Podría ser cualquier operación agregada, por lo que podría ser un valor. De nuevo, esto se puede almacenar en NCache como una entidad separada.

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

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

	return shipper;

}

Y de manera similar, podría ser una suma de conteo. Podría ser cualquier operación agregada, por lo que podría ser un valor. Una vez más, esto se puede almacenar en NCache como una entidad separada.

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

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

}

Arquitectura de almacenamiento en caché distribuida

Entonces, esto cubre nuestro seminario web en lo que respecta a la parte técnica. Hacia el final, le mostraré algo de arquitectura de almacenamiento en caché distribuido.

Alta disponibilidad

NCache como producto es muy, escalable, rápido. Es algo que se basa en la arquitectura de igual a igual en el protocolo. No hay un único punto de falla. Puede agregar o eliminar servidores sobre la marcha desde un caché en ejecución. No es necesario que detenga el caché ni ninguno de los clientes que están conectados a él. Entonces, de forma dinámica, puede realizar cambios en un clúster de caché en ejecución.

alta disponibilidad

Topologías de almacenamiento en caché

Entonces nuestra topología más popular es Caché de réplica de partición. Esto le permite simplemente distribuir datos en todos los servidores en forma de particiones. Entonces, están agrupando los recursos de memoria, los recursos computacionales, y eso le presenta una capacidad lógica y cada servicio también tiene una copia de seguridad. Server1 es una copia de seguridad en 2. Serve2 es una copia de seguridad en 1 y Serve3 es una copia de seguridad en Serve1. Por lo tanto, de forma rotativa, cada servidor tiene una copia de seguridad en otro servidor.

topologías de almacenamiento en caché

Caché del cliente (caché cercano)

Del mismo modo, esta es una topología muy rápida, muy escalable y la más popular. También puedes tener un caché del cliente que puede ejecutarse en su propio cuadro de aplicación. Es un caché local pero está sincronizado con el caché del servidor. El subconjunto de los datos se llevaría automáticamente a la memoria caché y sin ningún cambio de código. Esto mejora su rendimiento si sus datos son en su mayoría de naturaleza de referencia. Entonces, una vez que carga en el caché y luego comienza a llamar a este subconjunto de datos llamando a FromCacheOnly, el caché del cliente realmente ayudaría en ese caso.

cliente-caché

Replicación WAN de caché

Replicación WAN es otra característica, la replicación del puente. Puede tener sitios de datos activo-pasivo o activo-activo. Todos los datos, los datos de EF Core, las sesiones de ASP.NET o los datos normales se pueden transferir al sitio de destino a través de la WAN de forma activa-pasiva o activa-activa. Entonces, esto es lo que NCache cubiertas como parte de ella.

wan-replicación

Conclusión

Solo para reiterar que me tomaré un minuto más antes de entregárselo a Nick. Por lo tanto, hablamos sobre entidades únicas y colecciones de entidades de almacenamiento utilizando API directas. Eso fue ligeramente diferente en términos de métodos de extensión y luego hablamos de métodos de extensión que eran de naturaleza muy simple y, ya sabes, también de naturaleza más flexible. FromCache fue el primer método que obtiene algo del caché si existe, si no lo hace, lo obtiene automáticamente de la fuente de datos, a diferencia de las API directas donde debe implementarlo usted mismo. También construye las teclas y las opciones relacionadas que configura aquí.

Luego hablamos de datos de referencia y transaccionales. Para manejar datos de referencia, debe cargar datos completos mediante LoadIntoCache y debe llamar a FromCacheOnly. LoadIntoCache siempre se ejecuta contra la base de datos y luego, FromCacheOnly, solo se ejecuta contra el caché y luego hablamos sobre los datos transaccionales que puede manejar con la ayuda de FromCache y configura algunos vencimientos. Datos de referencia, para mantenerlos actualizados, debe usar vencimientos y luego usar recarga automática o no usar vencimientos y luego recargar manualmente usando LoadIntoCache. Luego hablamos sobre los datos transaccionales, que debe generar, algún tipo de vencimiento y usar FromCache para que, si existe en el caché, lo obtenga. Si no existe en el caché, siempre lo obtiene de la base de datos.

Entonces, eso concluye nuestra presentación. Por favor, hágamelo saber si hay alguna pregunta.

Siempre puede comunicarse con nosotros en support@alachisoft.com. Si tiene alguna consulta técnica, también puede comunicarse con nosotros a través de sales@alachisoft.com. Si deseas echarle un vistazo, descargar el producto, puedes ir a nuestra web alachisoft.com y puedes descargar NCache y viene con una versión de prueba de 30 días que puede usar y si tiene alguna pregunta, háganoslo saber, de lo contrario, muchas gracias por asistir a este programa de hoy, el seminario web, y nos vemos la próxima vez. Muchas gracias ron. Gracias chicos.

¿Qué hacer a continuación?

 
© Copyright Alachisoft 2002 - Todos los derechos reservados. NCache es una marca registrada de Diyatech Corp.