Skip to content

Commit

Permalink
Dist caching topic+sample update (#11238)
Browse files Browse the repository at this point in the history
  • Loading branch information
guardrex authored Mar 2, 2019
1 parent 68b39e5 commit 9eba48f
Show file tree
Hide file tree
Showing 12 changed files with 51 additions and 145 deletions.
65 changes: 17 additions & 48 deletions aspnetcore/performance/caching/distributed.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
title: Distributed caching in ASP.NET Core
author: guardrex
description: Learn how to use an ASP.NET Core distributed cache to improve app performance and scalability, especially in a cloud or server farm environment.
monikerRange: '>= aspnetcore-2.1'
ms.author: riande
ms.custom: mvc
ms.date: 02/26/2019
ms.date: 03/02/2019
uid: performance/caching/distributed
---
# Distributed caching in ASP.NET Core

By [Steve Smith](https://ardalis.com/) and [Luke Latham](https://github.com/guardrex)
By [Luke Latham](https://github.com/guardrex) and [Steve Smith](https://ardalis.com/)

A distributed cache is a cache shared by multiple app servers, typically maintained as an external service to the app servers that access it. A distributed cache can improve the performance and scalability of an ASP.NET Core app, especially when the app is hosted by a cloud service or a server farm.

Expand All @@ -35,30 +36,14 @@ To use a Redis distributed cache, reference the [Microsoft.AspNetCore.App metapa

::: moniker-end

::: moniker range="= aspnetcore-2.1"
::: moniker range="< aspnetcore-2.2"

To use a SQL Server distributed cache, reference the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app) or add a package reference to the [Microsoft.Extensions.Caching.SqlServer](https://www.nuget.org/packages/Microsoft.Extensions.Caching.SqlServer) package.

To use a Redis distributed cache, reference the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app) and add a package reference to the [Microsoft.Extensions.Caching.Redis](https://www.nuget.org/packages/Microsoft.Extensions.Caching.Redis) package. The Redis package isn't included in the `Microsoft.AspNetCore.App` package, so you must reference the Redis package separately in your project file.

::: moniker-end

::: moniker range="= aspnetcore-2.0"

To use a SQL Server distributed cache, reference the [Microsoft.AspNetCore.All metapackage](xref:fundamentals/metapackage) or add a package reference to the [Microsoft.Extensions.Caching.SqlServer](https://www.nuget.org/packages/Microsoft.Extensions.Caching.SqlServer) package.

To use a Redis distributed cache, reference the [Microsoft.AspNetCore.All metapackage](xref:fundamentals/metapackage) or add a package reference to the [Microsoft.Extensions.Caching.Redis](https://www.nuget.org/packages/Microsoft.Extensions.Caching.Redis) package. The Redis package is included in `Microsoft.AspNetCore.All` package, so you don't need to reference the Redis package separately in your project file.

::: moniker-end

::: moniker range="< aspnetcore-2.0"

To use a SQL Server distributed cache, add a package reference to the [Microsoft.Extensions.Caching.SqlServer](https://www.nuget.org/packages/Microsoft.Extensions.Caching.SqlServer) package.

To use a Redis distributed cache, add a package reference to the [Microsoft.Extensions.Caching.Redis](https://www.nuget.org/packages/Microsoft.Extensions.Caching.Redis) package.

::: moniker-end

## IDistributedCache interface

The <xref:Microsoft.Extensions.Caching.Distributed.IDistributedCache> interface provides the following methods to manipulate items in the distributed cache implementation:
Expand All @@ -85,27 +70,14 @@ The Distributed Memory Cache is a useful implementation:
* In development and testing scenarios.
* When a single server is used in production and memory consumption isn't an issue. Implementing the Distributed Memory Cache abstracts cached data storage. It allows for implementing a true distributed caching solution in the future if multiple nodes or fault tolerance become necessary.

The sample app makes use of the Distributed Memory Cache when the app is run in the Development environment:
The sample app makes use of the Distributed Memory Cache when the app is run in the Development environment in `Startup.ConfigureServices`:

[!code-csharp[](distributed/samples/2.x/DistCacheSample/Startup.cs?name=snippet_ConfigureServices&highlight=5)]
[!code-csharp[](distributed/samples/2.x/DistCacheSample/Startup.cs?name=snippet_AddDistributedMemoryCache)]

### Distributed SQL Server Cache

The Distributed SQL Server Cache implementation (<xref:Microsoft.Extensions.DependencyInjection.SqlServerCachingServicesExtensions.AddDistributedSqlServerCache*>) allows the distributed cache to use a SQL Server database as its backing store. To create a SQL Server cached item table in a SQL Server instance, you can use the `sql-cache` tool. The tool creates a table with the name and schema that you specify.

::: moniker range="< aspnetcore-2.1"

Add `SqlConfig.Tools` to the `<ItemGroup>` element of the project file and run `dotnet restore`.

```xml
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.Extensions.Caching.SqlConfig.Tools"
Version="2.0.2" />
</ItemGroup>
```

::: moniker-end

Create a table in SQL Server by running the `sql-cache create` command. Provide the SQL Server instance (`Data Source`), database (`Initial Catalog`), schema (for example, `dbo`), and table name (for example, `TestCache`):

```console
Expand All @@ -125,32 +97,29 @@ The table created by the `sql-cache` tool has the following schema:
> [!NOTE]
> An app should manipulate cache values using an instance of <xref:Microsoft.Extensions.Caching.Distributed.IDistributedCache>, not a <xref:Microsoft.Extensions.Caching.SqlServer.SqlServerCache>.
The sample app implements <xref:Microsoft.Extensions.Caching.SqlServer.SqlServerCache> in a non-Development environment:
The sample app implements <xref:Microsoft.Extensions.Caching.SqlServer.SqlServerCache> in a non-Development environment in `Startup.ConfigureServices`:

[!code-csharp[](distributed/samples/2.x/DistCacheSample/Startup.cs?name=snippet_ConfigureServices&highlight=9-15)]
[!code-csharp[](distributed/samples/2.x/DistCacheSample/Startup.cs?name=snippet_AddDistributedSqlServerCache)]

> [!NOTE]
> A <xref:Microsoft.Extensions.Caching.SqlServer.SqlServerCacheOptions.ConnectionString*> (and optionally, <xref:Microsoft.Extensions.Caching.SqlServer.SqlServerCacheOptions.SchemaName*> and <xref:Microsoft.Extensions.Caching.SqlServer.SqlServerCacheOptions.TableName*>) are typically stored outside of source control (for example, stored by the [Secret Manager](xref:security/app-secrets) or in *appsettings.json*/*appsettings.{Environment}.json* files). The connection string may contain credentials that should be kept out of source control systems.
> A <xref:Microsoft.Extensions.Caching.SqlServer.SqlServerCacheOptions.ConnectionString*> (and optionally, <xref:Microsoft.Extensions.Caching.SqlServer.SqlServerCacheOptions.SchemaName*> and <xref:Microsoft.Extensions.Caching.SqlServer.SqlServerCacheOptions.TableName*>) are typically stored outside of source control (for example, stored by the [Secret Manager](xref:security/app-secrets) or in *appsettings.json*/*appsettings.{ENVIRONMENT}.json* files). The connection string may contain credentials that should be kept out of source control systems.
### Distributed Redis Cache

[Redis](https://redis.io/) is an open source in-memory data store, which is often used as a distributed cache. You can use Redis locally, and you can configure an [Azure Redis Cache](https://azure.microsoft.com/services/cache/) for an Azure-hosted ASP.NET Core app.

::: moniker range=">= aspnetcore-2.2"

[Redis](https://redis.io/) is an open source in-memory data store, which is often used as a distributed cache. You can use Redis locally, and you can configure an [Azure Redis Cache](https://azure.microsoft.com/services/cache/) for an Azure-hosted ASP.NET Core app. An app configures the cache implementation using a `RedisCache` instance (`AddStackExchangeRedisCache`):
An app configures the cache implementation using a `RedisCache` instance (`AddStackExchangeRedisCache`) in a non-Development environment in `Startup.ConfigureServices`:

```csharp
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "localhost";
options.InstanceName = "SampleInstance";
});
```
[!code-csharp[](distributed/samples/2.x/DistCacheSample/Startup.cs?name=snippet_AddStackExchangeRedisCache)]

::: moniker-end

::: moniker range="< aspnetcore-2.2"

[Redis](https://redis.io/) is an open source in-memory data store, which is often used as a distributed cache. You can use Redis locally, and you can configure an [Azure Redis Cache](https://azure.microsoft.com/services/cache/) for an Azure-hosted ASP.NET Core app. An app configures the cache implementation using a <xref:Microsoft.Extensions.Caching.Redis.RedisCache> instance (<xref:Microsoft.Extensions.DependencyInjection.RedisCacheServiceCollectionExtensions.AddDistributedRedisCache*>):
An app configures the cache implementation using a <xref:Microsoft.Extensions.Caching.Redis.RedisCache> instance (<xref:Microsoft.Extensions.DependencyInjection.RedisCacheServiceCollectionExtensions.AddDistributedRedisCache*>):

```csharp
services.AddDistributedRedisCache(options =>
{
Expand Down Expand Up @@ -204,8 +173,8 @@ When SQL Server is used as a distributed cache backing store, use of the same da

## Additional resources

* [Redis Cache on Azure](https://azure.microsoft.com/documentation/services/redis-cache/)
* [SQL Database on Azure](https://azure.microsoft.com/documentation/services/sql-database/)
* [Redis Cache on Azure](/azure/azure-cache-for-redis/)
* [SQL Database on Azure](/azure/sql-database/)
* [ASP.NET Core IDistributedCache Provider for NCache in Web Farms](http://www.alachisoft.com/ncache/aspnet-core-idistributedcache-ncache.html) ([NCache on GitHub](https://github.com/Alachisoft/NCache))
* <xref:performance/caching/memory>
* <xref:fundamentals/change-tokens>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications</strong>. It can result in displaying sensitive information from exceptions to end users. For local debugging, enable the Development environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong> and restarting the app or adding <code>.UseEnvironment("Development")</code> to <code>WebHost</code> in <i>Program.cs</i> and restarting the app.
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

namespace SampleApp.Pages
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class ErrorModel : PageModel
{
public string RequestId { get; set; }

public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,8 @@
<p>This sample can be changed to use a Distributed Redis Cache:</p>
<ol>
<li>
Swap the Distributed SQL Server Cache service registration (<code>AddDistributedSqlServerCache</code>) in <code>Startup.ConfigureServices</code> with Redis service registrations:
<pre><code>services.AddDistributedRedisCache(options =>
{
options.Configuration = "localhost";
options.InstanceName = "SampleInstance";
});</code></pre>
Change the preprocessor directive (<code>#define</code>) at the top of the <em>Startup.cs</em> file from <code>SQLServer</code> to <code>Redis</code>:
<pre><code>#define Redis // SQLServer</code></pre>
</li>
<li>Install Redis on your local machine: Install the <a href="https://chocolatey.org/packages/redis-64/">Redis Chocolatey package</a> and run <code>redis-server</code> from a command prompt.</li>
<li>Set the <code>ASPNETCORE_ENVIRONMENT</code> environment variable to <code>Production</code>. In the Production environment, the app uses the Distributed Redis Cache when it starts.</li>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using System.Text;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewData["Title"] - Distributed Cache Sample</title>
<title>@ViewData["Title"]</title>
<style>body{margin:0;padding-bottom:20px;font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff;}h1{font-size:24px;margin:.67em 0;}pre{overflow:auto;}code,pre{font-family:monospace, monospace;font-size:1em;}button,input{margin:0;font:inherit;color:inherit;}button{overflow:visible;}button{text-transform:none;}input{line-height:normal;}*{box-sizing:border-box;}*:before,*:after{box-sizing:border-box;}input,button{font-family:inherit;font-size:inherit;line-height:inherit;}a{color:#337ab7;text-decoration:none;}h1,h2,h3,h4{font-family:inherit;font-weight:500;line-height:1.1;color:inherit;margin-top:20px;margin-bottom:10px;}h3{font-size:16px;}h4{font-size:18px;}p{margin:0 0 10px;}ol{margin-top:0;margin-bottom:10px;}code,pre{font-family:Menlo, Monaco, Consolas, "Courier New", monospace;}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px;}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;-radius:4px;}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0;}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto;}.container{width:800px;}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:normal;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;background-image:none;border:1px solid transparent;border-radius:4px;;color:#fff;background-color:green;border-color:gray;float:right}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;box-shadow:0 1px 1px rgba(0, 0, 0, .05);}.panel-body{padding:15px;}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px;}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit;}.panel-default{border-color:#ddd;}.panel-default > .panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd;}.clearfix:before,.clearfix:after,.container:before,.container:after,.panel-body:before,.panel-body:after{display:table;content:" ";}.clearfix:after,.container:after,.panel-body:after{clear:both;}.body-content{padding-left:15px;padding-right:15px;}.panel-body{font-size:16px;}</style>
</head>
<body>
<partial name="_CookieConsentPartial" />

<div class="container body-content">
@RenderBody()
</div>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

This sample illustrates the use of a distributed cache. This sample demonstrates the scenario described in the [Work with a distributed cache in ASP.NET Core](https://docs.microsoft.com/aspnet/core/performance/caching/distributed) topic.

Run the app in the Development environment. The app's Index page explains how the app works and how to configure the app to use a Distributed SQL Server Cache or Distributed Redis Cache.
In the Production environment, the sample app is configured to use a distributed SQL Server cache. To reconfigure the app to use a distributed Redis cache, change the preprocessor directive at the top of the *Startup.cs* file to use Redis (`#define Redis // SQLServer`). For more information, see [Preprocessor directives in sample code](https://docs.microsoft.com/aspnet/core/#preprocessor-directives-in-sample-code).
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="2.2.0" />
</ItemGroup>

</Project>
Loading

0 comments on commit 9eba48f

Please sign in to comment.