Saltar al contenido principal

Caché Distribuida en .NET

· 4 min de lectura

El uso de caché es una de las formas más eficaces de mejorar el rendimiento de una aplicación.
La mayoría de las aplicaciones de .NET comienzan con una simple caché en memoria usando MemoryCache o IMemoryCache. Esto funciona perfectamente cuando la aplicación se ejecuta en un solo servidor.

Sin embargo, las aplicaciones modernas rara vez se ejecutan en una sola máquina.

Cuando las aplicaciones escalan horizontalmente en varias instancias, la caché en memoria deja de funcionar de forma fiable. Cada instancia mantiene su propia caché, lo que significa que el estado de la aplicación se vuelve inconsistente en todo el clúster.

Aquí es donde la caché distribuida se vuelve esencial.


Caché Distribuida


El problema con las cachés en memoria

Considera una aplicación típica de ASP.NET desplegada detrás de un balanceador de carga.

          Load Balancer
|
---------------------------
| | |
Server A Server B Server C

Cada servidor tiene su propia caché en memoria.

Si una solicitud actualiza datos en caché en el Servidor A, las cachés del Servidor B y del Servidor C quedan desactualizadas.

Esto da lugar a varios problemas:

  • estado de la aplicación inconsistente
  • entradas de caché obsoletas
  • calentamientos de caché duplicados
  • comportamiento impredecible

Para resolver este problema, la caché debe ser compartida entre todos los nodos.


¿Qué es una caché distribuida?

Una caché distribuida es una caché centralizada o en clúster a la que pueden acceder varias instancias de la aplicación.

En lugar de almacenar los datos en caché dentro del proceso de la aplicación, los datos se almacenan en un almacén clave‑valor distribuido.

           Application Nodes

App A App B App C
| | |
+---------+---------+
|
Distributed Cache

Todos los nodos de la aplicación leen y escriben entradas de caché desde el mismo almacén distribuido.

Esto garantiza:

  • datos en caché consistentes
  • estado de la aplicación compartido
  • mejor escalabilidad

Ejemplo básico de caché distribuida en .NET

Una caché distribuida se utiliza normalmente a través de una abstracción como IDistributedCache.

Ejemplo:

public class ProductService
{
private readonly IDistributedCache _cache;

public ProductService(IDistributedCache cache)
{
_cache = cache;
}

public async Task<string?> GetProductAsync(string id)
{
var cached = await _cache.GetStringAsync(id);

if (cached != null)
return cached;

var product = await LoadProductFromDatabase(id);

await _cache.SetStringAsync(id, product);

return product;
}

private Task<string> LoadProductFromDatabase(string id)
{
return Task.FromResult($"Product {id}");
}
}

La aplicación comprueba primero la caché. Si el valor no está presente, los datos se cargan desde la base de datos y luego se almacenan en la caché.

Este patrón se denomina caché aparte (cache‑aside).


Soluciones comunes de caché distribuida

Varias tecnologías proporcionan capacidades de caché distribuida.

Redis​

Redis es una de las cachés distribuidas más utilizadas.

Proporciona:

  • almacenamiento clave‑valor
  • alto rendimiento
  • operaciones en memoria

Sin embargo, Redis a menudo requiere componentes adicionales cuando se utiliza para la coordinación distribuida.


Cachés respaldadas por bases de datos​

Algunas aplicaciones utilizan bases de datos relacionales como cachés.

Aunque es sencillo, este enfoque introduce:

  • contención en la base de datos
  • rendimiento reducido
  • escalabilidad limitada

Plataformas clave‑valor distribuidas​

Los sistemas distribuidos modernos a menudo utilizan plataformas clave‑valor distribuidas que proporcionan tanto caché como primitivas de coordinación.

Estos sistemas admiten:

  • caché distribuida
  • bloqueos distribuidos
  • elección de líder
  • notificaciones de cambios
  • coordinación del clúster

Uso de Clustron como caché distribuida

Clustron proporciona una plataforma clave‑valor distribuida diseñada para aplicaciones de .NET.

Como se ejecuta como un clúster distribuido, todas las instancias de la aplicación interactúan con el mismo almacén de datos compartido.

Ejemplo:

using Clustron.DKV.Client;

var client = await DKVClient.InitializeRemote(
"teststore",
new[]
{
new DkvServerInfo("localhost", 7861)
});

await client.PutAsync("product:1", "Laptop");

var value = await client.GetAsync<string>("product:1");

Console.WriteLine(value);

En este ejemplo:

  • los nodos de la aplicación se conectan al clúster
  • los datos se almacenan en el almacén distribuido
  • todos los nodos ven los mismos datos

Esto permite que la caché permanezca consistente en todo el clúster.


Cuándo usar la caché distribuida

La caché distribuida es especialmente útil en sistemas que:

  • ejecutan varias instancias de la aplicación
  • procesan grandes volúmenes de solicitudes
  • dependen en gran medida de las lecturas de la base de datos
  • requieren un estado de aplicación compartido

Los casos de uso típicos incluyen:

  • aplicaciones web de ASP.NET
  • arquitecturas de microservicios
  • sistemas de procesamiento en segundo plano
  • plataformas de API

Resumen

La caché en memoria funciona bien para aplicaciones de un solo servidor, pero los sistemas distribuidos modernos requieren una capa de caché compartida.

La caché distribuida permite que varias instancias de la aplicación compartan los mismos datos en caché, mejorando la escalabilidad y la consistencia.

Plataformas como Clustron proporcionan un almacén clave‑valor distribuido que facilita la implementación de la caché distribuida y la coordinación en aplicaciones de .NET.