Almacenamiento en caché distribuido en ASP.NET Core

Por Smithsin Nasir y Steve Smith

Una caché distribuida es una caché compartida por varios servidores de aplicaciones, que normalmente se mantiene como un servicio externo para los servidores de aplicaciones que acceden a ella. Una caché distribuida puede mejorar el rendimiento y la escalabilidad de una aplicación ASP.NET Core, especialmente cuando la aplicación se hospeda en un servicio en la nube o una granja de servidores.

Una caché distribuida tiene varias ventajas con respecto a otros escenarios de almacenamiento en caché en los que los datos almacenados en caché se almacenan en servidores de aplicaciones individuales.

Cuando se distribuyen los datos almacenados en caché, los datos:

  • Es coherente (coherente) entre las solicitudes a varios servidores.
  • Sobrevive a los reinicios del servidor y a las implementaciones de aplicaciones.
  • No usa memoria local.

La configuración de caché distribuida es específica de la implementación. En este artículo se describe cómo configurar SQL Server cachés distribuidas de Redis. También hay implementaciones de terceros disponibles, como NCache (NCache en GitHub). Independientemente de la implementación seleccionada, la aplicación interactúa con la memoria caché mediante la IDistributedCache interfaz .

Vea o descargue el código de ejemplo (cómo descargarlo)

Requisitos previos

Para usar una SQL Server caché distribuida, agregue una referencia de paquete al paquete Microsoft.Extensions.Caching.SqlServer.

Para usar una caché distribuida de Redis, agregue una referencia de paquete al paquete Microsoft.Extensions.Caching.StackExchangeRedis.

Para usar la caché distribuida de NCache, agregue una referencia de paquete al paquete NCache.Microsoft.Extensions.Caching.OpenSource.

Interfaz IDistributedCache

La IDistributedCache interfaz proporciona los métodos siguientes para manipular elementos en la implementación de caché distribuida:

  • Get, : acepta una clave de cadena y recupera un elemento almacenado en caché como una matriz GetAsync si se encuentra en la memoria byte[] caché.
  • Set, SetAsync : agrega un elemento (como matriz) a la memoria caché mediante una clave de byte[] cadena.
  • Refresh, : actualiza un elemento de la memoria caché en función de su clave y restablece su tiempo de espera de expiración RefreshAsync deslizante (si lo hubiera).
  • Remove, RemoveAsync : quita un elemento de caché basado en su clave de cadena.

Establecimiento de servicios de almacenamiento en caché distribuidos

Registre una implementación de IDistributedCache en Startup.ConfigureServices . Las implementaciones proporcionadas por el marco descritas en este tema incluyen:

Caché de memoria distribuida

La caché de memoria distribuida ( AddDistributedMemoryCache ) es una implementación proporcionada por el marco de trabajo de que almacena elementos en IDistributedCache memoria. La caché de memoria distribuida no es una caché distribuida real. La instancia de la aplicación almacena los elementos almacenados en caché en el servidor donde se ejecuta la aplicación.

La caché de memoria distribuida es una implementación útil:

  • En escenarios de desarrollo y pruebas.
  • Cuando se usa un solo servidor en producción y el consumo de memoria no es un problema. La implementación de la caché de memoria distribuida abstrae el almacenamiento de datos almacenado en caché. Permite implementar una verdadera solución de almacenamiento en caché distribuido en el futuro si son necesarios varios nodos o tolerancia a errores.

La aplicación de ejemplo usa la caché de memoria distribuida cuando la aplicación se ejecuta en el entorno de desarrollo en Startup.ConfigureServices :

services.AddDistributedMemoryCache();

Caché de SQL Server distribuida

La implementación de distributed SQL Server Cache ( ) permite que la caché distribuida use una base de datos SQL Server como memoria AddDistributedSqlServerCache subyacente. Para crear una SQL Server de elementos almacenados en caché en SQL Server instancia de , puede usar la sql-cache herramienta . La herramienta crea una tabla con el nombre y el esquema que especifique.

Cree una tabla en SQL Server ejecutando el sql-cache create comando . Proporcione la SQL Server de datos ( ), la base de datos ( ), el esquema (por ejemplo, ) y el Data Source Initial Catalog nombre de tabla dbo (por ejemplo, TestCache ):

dotnet sql-cache create "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache

Se registra un mensaje para indicar que la herramienta se ha realizado correctamente:

Table and index were created successfully.

La tabla creada por la sql-cache herramienta tiene el esquema siguiente:

Tabla de caché de SqlServer

Nota

Una aplicación debe manipular los valores de caché mediante una instancia de IDistributedCache , no un SqlServerCache .

La aplicación de ejemplo implementa SqlServerCache en un entorno que no es de desarrollo en Startup.ConfigureServices :

services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = 
        _config["DistCache_ConnectionString"];
    options.SchemaName = "dbo";
    options.TableName = "TestCache";
});

Nota

(y, opcionalmente, y ) normalmente se almacenan fuera del control de código fuente (por ejemplo, almacenados por el Administrador de secretos ConnectionString SchemaName o en TableName appsettings.json / appsettings).{ ENVIRONMENT}.json). La cadena de conexión puede contener credenciales que deben mantenerse fuera de los sistemas de control de código fuente.

Distribución Redis Cache

Redis es un almacén de datos en memoria de código abierto, que a menudo se usa como caché distribuida. Puede configurar una instancia de Azure Redis Cache para una aplicación de ASP.NET Core hospedada en Azure y usar una instancia de Azure Redis Cache desarrollo local.

Una aplicación configura la implementación de caché mediante una RedisCache instancia ( AddStackExchangeRedisCache ).

  1. Cree una Azure Cache for Redis.
  2. Copie la cadena de conexión principal (StackExchange.Redis) en Configuración.
    • Desarrollo local: guarde la cadena de conexión con secret Manager.
    • Azure: guarde la cadena de conexión en la App Service configuración u otro almacén seguro.

El código siguiente habilita el Azure Cache for Redis:

public void ConfigureServices(IServiceCollection services)
{
    if (_hostContext.IsDevelopment())
    {
        services.AddDistributedMemoryCache();
    }
    else
    {
        services.AddStackExchangeRedisCache(options =>
        {
            options.Configuration = _config["MyRedisConStr"];
            options.InstanceName = "SampleInstance";
        });
    }

    services.AddRazorPages();
}

En el código anterior se supone que la cadena de conexión principal (StackExchange.Redis) se guardó en la configuración con el nombre de clave MyRedisConStr .

Para más información, consulte Azure Cache for Redis.

Consulte este GitHub para obtener una explicación sobre los enfoques alternativos a una caché de Redis local.

Caché distribuida de NCache

NCache es una caché distribuida en memoria de código abierto desarrollada de forma nativa en .NET y .NET Core. NCache funciona localmente y configurado como un clúster de caché distribuida para una aplicación de ASP.NET Core que se ejecuta en Azure o en otras plataformas de hospedaje.

Para instalar y configurar NCache en el equipo local, consulte Tareas iniciales guía de Windows (.NET y .NET Core).

Para configurar NCache:

  1. Instale el código abierto de NCache NuGet.

  2. Configure el clúster de caché en client.ncconf.

  3. Agrega el código siguiente a Startup.ConfigureServices:

    services.AddNCacheDistributedCache(configuration =>    
    {        
        configuration.CacheName = "demoClusteredCache";
        configuration.EnableLogs = true;
        configuration.ExceptionsEnabled = true;
    });
    

Uso de la caché distribuida

Para usar la IDistributedCache interfaz , solicite una instancia de desde cualquier constructor de la IDistributedCache aplicación. La instancia se proporciona mediante la inserción de dependencias (DI).

Cuando se inicia la aplicación de ejemplo, IDistributedCache se inserta en Startup.Configure . La hora actual se almacena en caché IHostApplicationLifetime mediante (para obtener más información, vea Host genérico: IHostApplicationLifetime):

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, 
    IHostApplicationLifetime lifetime, IDistributedCache cache)
{
    lifetime.ApplicationStarted.Register(() =>
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
        cache.Set("cachedTimeUTC", encodedCurrentTimeUTC, options);
    });

La aplicación de ejemplo inserta IDistributedCache en para que la use la página IndexModel Índice.

Cada vez que se carga la página Índice, la memoria caché se comprueba para la hora almacenada en caché en OnGetAsync . Si la hora almacenada en caché no ha expirado, se muestra la hora. Si han transcurrido 20 segundos desde la última vez que se tuvo acceso a la hora almacenada en caché (la última vez que se cargó esta página), la página muestra Tiempo de expiración en caché.

Actualice inmediatamente la hora almacenada en caché a la hora actual seleccionando el botón Restablecer hora almacenada en caché. El botón desencadena el OnPostResetCachedTime método de controlador.

public class IndexModel : PageModel
{
    private readonly IDistributedCache _cache;

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

    public string CachedTimeUTC { get; set; }

    public async Task OnGetAsync()
    {
        CachedTimeUTC = "Cached Time Expired";
        var encodedCachedTimeUTC = await _cache.GetAsync("cachedTimeUTC");

        if (encodedCachedTimeUTC != null)
        {
            CachedTimeUTC = Encoding.UTF8.GetString(encodedCachedTimeUTC);
        }
    }

    public async Task<IActionResult> OnPostResetCachedTime()
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
        await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options);

        return RedirectToPage();
    }
}

Nota

No es necesario usar una duración singleton o con ámbito para las instancias (al menos para las IDistributedCache implementaciones integradas).

También puede crear una instancia siempre que necesite una en lugar de usar la di di, pero la creación de una instancia en el código puede dificultar la prueba del código y infringe el Principio de IDistributedCache dependencias explícitas .

Recomendaciones

A la hora de decidir qué implementación IDistributedCache de es la mejor para la aplicación, tenga en cuenta lo siguiente:

  • Infraestructura existente
  • Requisitos de rendimiento
  • Coste
  • Experiencia en equipo

Las soluciones de almacenamiento en caché normalmente se basan en el almacenamiento en memoria para proporcionar una recuperación rápida de los datos almacenados en caché, pero la memoria es un recurso limitado y costoso de expandir. Almacene solo los datos usados habitualmente en una memoria caché.

Por lo general, una caché de Redis proporciona un mayor rendimiento y una latencia menor que una SQL Server caché. Sin embargo, normalmente es necesario realizar pruebas comparativas para determinar las características de rendimiento de las estrategias de almacenamiento en caché.

Cuando SQL Server se usa como almacén de respaldo de caché distribuida, el uso de la misma base de datos para la memoria caché y el almacenamiento y recuperación de datos normales de la aplicación pueden afectar negativamente al rendimiento de ambos. Se recomienda usar una instancia de SQL Server dedicada para el almacén de respaldo de caché distribuida.

Recursos adicionales

Una caché distribuida es una caché compartida por varios servidores de aplicaciones, que normalmente se mantiene como un servicio externo a los servidores de aplicaciones que acceden a ella. Una caché distribuida puede mejorar el rendimiento y la escalabilidad de una aplicación ASP.NET Core, especialmente cuando la aplicación está hospedada por un servicio en la nube o una granja de servidores.

Una caché distribuida tiene varias ventajas con respecto a otros escenarios de almacenamiento en caché en los que los datos almacenados en caché se almacenan en servidores de aplicaciones individuales.

Cuando se distribuyen los datos almacenados en caché, los datos:

  • Es coherente (coherente) entre las solicitudes a varios servidores.
  • Sobrevive a los reinicios del servidor y a las implementaciones de aplicaciones.
  • No usa memoria local.

La configuración de caché distribuida es específica de la implementación. En este artículo se describe cómo configurar SQL Server cachés distribuidas de Redis. También hay implementaciones de terceros disponibles, como NCache (NCache en GitHub). Independientemente de la implementación seleccionada, la aplicación interactúa con la memoria caché mediante la IDistributedCache interfaz .

Vea o descargue el código de ejemplo (cómo descargarlo)

Requisitos previos

Para usar una SQL Server caché distribuida, haga referencia al metapaquete Microsoft.AspNetCore.App o agregue una referencia de paquete al paquete Microsoft.Extensions.Caching.SqlServer.

Para usar una caché distribuida en Redis, haga referencia al metapaquete Microsoft.AspNetCore.App y agregue una referencia de paquete al paquete Microsoft.Extensions.Caching.StackExchangeRedis. El paquete de Redis no está incluido en el paquete, por lo que debe hacer referencia al Microsoft.AspNetCore.App paquete de Redis por separado en el archivo del proyecto.

Para usar la caché distribuida de NCache, haga referencia al metapaquete Microsoft.AspNetCore.App y agregue una referencia de paquete al paquete NCache.Microsoft.Extensions.Caching.OpenSource. El paquete NCache no se incluye en el paquete, por lo que debe hacer referencia al paquete Microsoft.AspNetCore.App NCache por separado en el archivo del proyecto.

Interfaz IDistributedCache

La IDistributedCache interfaz proporciona los métodos siguientes para manipular elementos en la implementación de caché distribuida:

  • Get, : acepta una clave de cadena y recupera un elemento almacenado en caché como una matriz GetAsync si se encuentra en la memoria byte[] caché.
  • Set, SetAsync : agrega un elemento (como byte[] matriz) a la memoria caché mediante una clave de cadena.
  • Refresh, : actualiza un elemento de la memoria caché en función de su clave y restablece el tiempo de espera de expiración RefreshAsync deslizante (si hay alguno).
  • Remove, RemoveAsync : quita un elemento de caché en función de su clave de cadena.

Establecimiento de servicios de almacenamiento en caché distribuidos

Registre una implementación de IDistributedCache en Startup.ConfigureServices . Las implementaciones proporcionadas por el marco descritas en este tema incluyen:

Caché de memoria distribuida

La caché de memoria distribuida ( AddDistributedMemoryCache ) es una implementación proporcionada por el marco de trabajo de que almacena elementos en IDistributedCache memoria. La caché de memoria distribuida no es una caché distribuida real. La instancia de la aplicación almacena los elementos almacenados en caché en el servidor donde se ejecuta la aplicación.

La caché de memoria distribuida es una implementación útil:

  • En escenarios de desarrollo y pruebas.
  • Cuando se usa un solo servidor en producción y el consumo de memoria no es un problema. La implementación de la caché de memoria distribuida abstrae el almacenamiento de datos almacenados en caché. Permite implementar una verdadera solución de almacenamiento en caché distribuido en el futuro si son necesarios varios nodos o tolerancia a errores.

La aplicación de ejemplo usa la caché de memoria distribuida cuando la aplicación se ejecuta en el entorno de desarrollo en Startup.ConfigureServices :

services.AddDistributedMemoryCache();

Caché de SQL Server distribuida

La implementación de SQL Server caché distribuida ( ) permite que la caché distribuida use una base SQL Server datos como su AddDistributedSqlServerCache almacén de respaldo. Para crear una SQL Server de elementos en caché en una SQL Server, puede usar la sql-cache herramienta . La herramienta crea una tabla con el nombre y el esquema que especifique.

Cree una tabla en SQL Server mediante la ejecución del sql-cache create comando . Proporcione la SQL Server de datos ( ), la base de datos ( ), el esquema (por ejemplo, ) y el Data Source Initial Catalog nombre de tabla dbo (por ejemplo, TestCache ):

dotnet sql-cache create "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache

Se registra un mensaje para indicar que la herramienta se ha realizado correctamente:

Table and index were created successfully.

La tabla creada por la sql-cache herramienta tiene el esquema siguiente:

Tabla de caché de SqlServer

Nota

Una aplicación debe manipular los valores de caché mediante una instancia de IDistributedCache , no un SqlServerCache .

La aplicación de ejemplo implementa SqlServerCache en un entorno que no es de desarrollo en Startup.ConfigureServices :

services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = 
        _config["DistCache_ConnectionString"];
    options.SchemaName = "dbo";
    options.TableName = "TestCache";
});

Nota

Un (y opcionalmente, y ) normalmente se almacenan fuera del control de código fuente (por ejemplo, almacenados por el Administrador de secretos ConnectionString SchemaName o en TableName appsettings.json / appsettings.{ ENVIRONMENT}.json). La cadena de conexión puede contener credenciales que deben mantenerse fuera de los sistemas de control de código fuente.

Distribución Redis Cache

Redis es un almacén de datos en memoria de código abierto, que a menudo se usa como caché distribuida. Puede usar Redis localmente y configurar una instancia de Azure Redis Cache para una aplicación de almacenamiento ASP.NET Core Azure.

Una aplicación configura la implementación de caché mediante una instancia ( ) en un entorno que no RedisCache es de desarrollo en AddStackExchangeRedisCache Startup.ConfigureServices :

services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = "localhost";
    options.InstanceName = "SampleInstance";
});

Para instalar Redis en el equipo local:

  1. Instale el paquete Chocolatey Redis.
  2. Ejecute redis-server desde un símbolo del sistema.

Caché de NCache distribuida

NCache es una caché distribuida en memoria de código abierto desarrollada de forma nativa en .NET y .NET Core. NCache funciona localmente y configurado como un clúster de caché distribuida para una aplicación de ASP.NET Core que se ejecuta en Azure o en otras plataformas de hospedaje.

Para instalar y configurar NCache en el equipo local, consulte Tareas iniciales guía de Windows (.NET y .NET Core).

Para configurar NCache:

  1. Instale el código abierto de NCache NuGet.

  2. Configure el clúster de caché en client.ncconf.

  3. Agrega el código siguiente a Startup.ConfigureServices:

    services.AddNCacheDistributedCache(configuration =>    
    {        
        configuration.CacheName = "demoClusteredCache";
        configuration.EnableLogs = true;
        configuration.ExceptionsEnabled = true;
    });
    

Uso de la caché distribuida

Para usar la IDistributedCache interfaz , solicite una instancia de desde cualquier constructor de la IDistributedCache aplicación. La instancia se proporciona mediante la inserción de dependencias (DI).

Cuando se inicia la aplicación de ejemplo, IDistributedCache se inserta en Startup.Configure . La hora actual se almacena en caché IApplicationLifetime mediante (para obtener más información, vea Host web: interfaz IApplicationLifetime):

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
    IApplicationLifetime lifetime, IDistributedCache cache)
{
    lifetime.ApplicationStarted.Register(() =>
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
        cache.Set("cachedTimeUTC", encodedCurrentTimeUTC, options);
    });

La aplicación de ejemplo inserta IDistributedCache en para su uso en la página IndexModel Índice.

Cada vez que se carga la página Índice, la memoria caché se comprueba para la hora almacenada en caché en OnGetAsync . Si la hora almacenada en caché no ha expirado, se muestra la hora. Si han transcurrido 20 segundos desde la última vez que se tuvo acceso a la hora almacenada en caché (la última vez que se cargó esta página), la página muestra Tiempo en caché expirado.

Actualice inmediatamente la hora almacenada en caché a la hora actual seleccionando el botón Restablecer hora almacenada en caché. El botón desencadena el OnPostResetCachedTime método de controlador.

public class IndexModel : PageModel
{
    private readonly IDistributedCache _cache;

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

    public string CachedTimeUTC { get; set; }

    public async Task OnGetAsync()
    {
        CachedTimeUTC = "Cached Time Expired";
        var encodedCachedTimeUTC = await _cache.GetAsync("cachedTimeUTC");

        if (encodedCachedTimeUTC != null)
        {
            CachedTimeUTC = Encoding.UTF8.GetString(encodedCachedTimeUTC);
        }
    }

    public async Task<IActionResult> OnPostResetCachedTime()
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
        await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options);

        return RedirectToPage();
    }
}

Nota

No es necesario usar una duración singleton o con ámbito para las instancias (al menos para las IDistributedCache implementaciones integradas).

También puede crear una instancia siempre que necesite una en lugar de usar la dependencia de dependencias, pero la creación de una instancia en el código puede dificultar la prueba del código y infringe el Principio de IDistributedCache dependencias explícitas .

Recomendaciones

Al decidir qué implementación de IDistributedCache es mejor para la aplicación, tenga en cuenta lo siguiente:

  • Infraestructura existente
  • Requisitos de rendimiento
  • Coste
  • Experiencia de equipo

Las soluciones de almacenamiento en caché normalmente se basan en el almacenamiento en memoria para proporcionar una recuperación rápida de los datos almacenados en caché, pero la memoria es un recurso limitado y costoso de expandir. Almacene solo los datos usados habitualmente en una memoria caché.

Por lo general, una caché de Redis proporciona un mayor rendimiento y una latencia más baja que una SQL Server caché. Sin embargo, las pruebas comparativas suelen ser necesarias para determinar las características de rendimiento de las estrategias de almacenamiento en caché.

Cuando SQL Server se usa como un almacén de respaldo de caché distribuida, el uso de la misma base de datos para la memoria caché y el almacenamiento y recuperación de datos normales de la aplicación pueden afectar negativamente al rendimiento de ambos. Se recomienda usar una instancia de SQL Server dedicada para el almacén de respaldo de caché distribuida.

Recursos adicionales

Una caché distribuida es una caché compartida por varios servidores de aplicaciones, que normalmente se mantiene como un servicio externo para los servidores de aplicaciones que acceden a ella. Una caché distribuida puede mejorar el rendimiento y la escalabilidad de una aplicación ASP.NET Core, especialmente cuando la aplicación se hospeda en un servicio en la nube o una granja de servidores.

Una caché distribuida tiene varias ventajas con respecto a otros escenarios de almacenamiento en caché en los que los datos almacenados en caché se almacenan en servidores de aplicaciones individuales.

Cuando se distribuyen los datos almacenados en caché, los datos:

  • Es coherente (coherente) entre las solicitudes a varios servidores.
  • Sobrevive a los reinicios del servidor y a las implementaciones de aplicaciones.
  • No usa memoria local.

La configuración de caché distribuida es específica de la implementación. En este artículo se describe cómo configurar SQL Server cachés distribuidas de Redis. También hay implementaciones de terceros disponibles, como NCache (NCache en GitHub). Independientemente de la implementación seleccionada, la aplicación interactúa con la memoria caché mediante la IDistributedCache interfaz .

Vea o descargue el código de ejemplo (cómo descargarlo)

Requisitos previos

Para usar una SQL Server caché distribuida, haga referencia al metapaquete Microsoft.AspNetCore.App o agregue una referencia de paquete al paquete Microsoft.Extensions.Caching.SqlServer.

Para usar una caché distribuida de Redis, haga referencia al metapaquete Microsoft.AspNetCore.App y agregue una referencia de paquete al paquete Microsoft.Extensions.Caching.Redis. El paquete de Redis no se incluye en el paquete, por lo que debe hacer referencia al Microsoft.AspNetCore.App paquete de Redis por separado en el archivo del proyecto.

Para usar la caché distribuida de NCache, haga referencia al metapaquete Microsoft.AspNetCore.App y agregue una referencia de paquete al paquete NCache.Microsoft.Extensions.Caching.OpenSource. El paquete NCache no se incluye en el paquete, por lo que debe hacer referencia al paquete Microsoft.AspNetCore.App NCache por separado en el archivo del proyecto.

Interfaz IDistributedCache

La IDistributedCache interfaz proporciona los métodos siguientes para manipular elementos en la implementación de caché distribuida:

  • Get, : acepta una clave de cadena y recupera un elemento almacenado en caché como una matriz GetAsync si se encuentra en la memoria byte[] caché.
  • Set, SetAsync : agrega un elemento (como matriz) a la memoria caché mediante una clave de byte[] cadena.
  • Refresh, : actualiza un elemento de la memoria caché en función de su clave y restablece su tiempo de espera de expiración RefreshAsync deslizante (si lo hubiera).
  • Remove, RemoveAsync : quita un elemento de caché basado en su clave de cadena.

Establecimiento de servicios de almacenamiento en caché distribuidos

Registre una implementación de IDistributedCache en Startup.ConfigureServices . Las implementaciones proporcionadas por el marco descritas en este tema incluyen:

Caché de memoria distribuida

La caché de memoria distribuida ( AddDistributedMemoryCache ) es una implementación proporcionada por el marco de trabajo de que almacena elementos en IDistributedCache memoria. La caché de memoria distribuida no es una caché distribuida real. La instancia de la aplicación almacena los elementos almacenados en caché en el servidor donde se ejecuta la aplicación.

La caché de memoria distribuida es una implementación útil:

  • En escenarios de desarrollo y pruebas.
  • Cuando se usa un solo servidor en producción y el consumo de memoria no es un problema. La implementación de la caché de memoria distribuida abstrae el almacenamiento de datos almacenado en caché. Permite implementar una verdadera solución de almacenamiento en caché distribuido en el futuro si son necesarios varios nodos o tolerancia a errores.

La aplicación de ejemplo usa la caché de memoria distribuida cuando la aplicación se ejecuta en el entorno de desarrollo en Startup.ConfigureServices :

services.AddDistributedMemoryCache();

Caché de SQL Server distribuida

La implementación de distributed SQL Server Cache ( ) permite que la caché distribuida use una base de datos SQL Server como memoria AddDistributedSqlServerCache caché de respaldo. Para crear una SQL Server de elementos almacenados en caché en SQL Server instancia de , puede usar la sql-cache herramienta . La herramienta crea una tabla con el nombre y el esquema que especifique.

Cree una tabla en SQL Server mediante la ejecución del sql-cache create comando . Proporcione la SQL Server de datos ( ), la base de datos ( ), el esquema (por ejemplo, ) y el Data Source Initial Catalog nombre de tabla dbo (por ejemplo, TestCache ):

dotnet sql-cache create "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache

Se registra un mensaje para indicar que la herramienta se ha realizado correctamente:

Table and index were created successfully.

La tabla creada por la sql-cache herramienta tiene el esquema siguiente:

Tabla de caché de SqlServer

Nota

Una aplicación debe manipular los valores de caché mediante una instancia de IDistributedCache , no un SqlServerCache .

La aplicación de ejemplo implementa SqlServerCache en un entorno que no es de desarrollo en Startup.ConfigureServices :

services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = 
        _config["DistCache_ConnectionString"];
    options.SchemaName = "dbo";
    options.TableName = "TestCache";
});

Nota

(y, opcionalmente, y ) normalmente se almacenan fuera del control de código fuente (por ejemplo, almacenados por el Administrador de secretos ConnectionString SchemaName o en TableName appsettings.json / appsettings).{ ENVIRONMENT}.json). La cadena de conexión puede contener credenciales que deben mantenerse fuera de los sistemas de control de código fuente.

Distribución Redis Cache

Redis es un almacén de datos en memoria de código abierto, que a menudo se usa como caché distribuida. Puede usar Redis localmente y configurar una instancia de Azure Redis Cache para una aplicación hospedada ASP.NET Core Azure.

Una aplicación configura la implementación de caché mediante una RedisCache instancia ( AddDistributedRedisCache ):

services.AddDistributedRedisCache(options =>
{
    options.Configuration = "localhost";
    options.InstanceName = "SampleInstance";
});

Para instalar Redis en el equipo local:

  1. Instale el paquete de Chocolatey Redis.
  2. Ejecute redis-server desde un símbolo del sistema.

Caché distribuida de NCache

NCache es una caché distribuida en memoria de código abierto desarrollada de forma nativa en .NET y .NET Core. NCache funciona localmente y configurado como un clúster de caché distribuida para una aplicación de ASP.NET Core que se ejecuta en Azure o en otras plataformas de hospedaje.

Para instalar y configurar NCache en el equipo local, consulte Tareas iniciales guía de Windows (.NET y .NET Core).

Para configurar NCache:

  1. Instale el código abierto de NCache NuGet.

  2. Configure el clúster de caché en client.ncconf.

  3. Agrega el código siguiente a Startup.ConfigureServices:

    services.AddNCacheDistributedCache(configuration =>    
    {        
        configuration.CacheName = "demoClusteredCache";
        configuration.EnableLogs = true;
        configuration.ExceptionsEnabled = true;
    });
    

Uso de la caché distribuida

Para usar la IDistributedCache interfaz , solicite una instancia de desde cualquier constructor de la IDistributedCache aplicación. La instancia se proporciona mediante la inserción de dependencias (DI).

Cuando se inicia la aplicación de ejemplo, IDistributedCache se inserta en Startup.Configure . La hora actual se almacena en caché IApplicationLifetime mediante (para obtener más información, vea Host web: interfaz IApplicationLifetime):

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
    IApplicationLifetime lifetime, IDistributedCache cache)
{
    lifetime.ApplicationStarted.Register(() =>
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
        cache.Set("cachedTimeUTC", encodedCurrentTimeUTC, options);
    });

La aplicación de ejemplo inserta IDistributedCache en para que la use la página IndexModel Índice.

Cada vez que se carga la página Índice, la memoria caché se comprueba para la hora almacenada en caché en OnGetAsync . Si la hora almacenada en caché no ha expirado, se muestra la hora. Si han transcurrido 20 segundos desde la última vez que se tuvo acceso a la hora almacenada en caché (la última vez que se cargó esta página), la página muestra Tiempo de expiración en caché.

Actualice inmediatamente la hora almacenada en caché a la hora actual seleccionando el botón Restablecer hora almacenada en caché. El botón desencadena el OnPostResetCachedTime método de controlador.

public class IndexModel : PageModel
{
    private readonly IDistributedCache _cache;

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

    public string CachedTimeUTC { get; set; }

    public async Task OnGetAsync()
    {
        CachedTimeUTC = "Cached Time Expired";
        var encodedCachedTimeUTC = await _cache.GetAsync("cachedTimeUTC");

        if (encodedCachedTimeUTC != null)
        {
            CachedTimeUTC = Encoding.UTF8.GetString(encodedCachedTimeUTC);
        }
    }

    public async Task<IActionResult> OnPostResetCachedTime()
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
        await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options);

        return RedirectToPage();
    }
}

Nota

No es necesario usar una duración singleton o con ámbito para las instancias (al menos para las IDistributedCache implementaciones integradas).

También puede crear una instancia siempre que necesite una en lugar de usar la di di, pero la creación de una instancia en el código puede dificultar la prueba del código y infringe el Principio de IDistributedCache dependencias explícitas .

Recomendaciones

A la hora de decidir qué implementación IDistributedCache de es la mejor para la aplicación, tenga en cuenta lo siguiente:

  • Infraestructura existente
  • Requisitos de rendimiento
  • Coste
  • Experiencia en equipo

Las soluciones de almacenamiento en caché normalmente se basan en el almacenamiento en memoria para proporcionar una recuperación rápida de los datos almacenados en caché, pero la memoria es un recurso limitado y costoso de expandir. Almacene solo los datos usados habitualmente en una memoria caché.

Por lo general, una caché de Redis proporciona un mayor rendimiento y una latencia menor que una SQL Server caché. Sin embargo, normalmente es necesario realizar pruebas comparativas para determinar las características de rendimiento de las estrategias de almacenamiento en caché.

Cuando SQL Server se usa como almacén de respaldo de caché distribuida, el uso de la misma base de datos para la memoria caché y el almacenamiento y recuperación de datos normales de la aplicación pueden afectar negativamente al rendimiento de ambos. Se recomienda usar una instancia de SQL Server dedicada para el almacén de respaldo de caché distribuida.

Recursos adicionales