C#-缓存(二)_分布式缓存DistributedCache

  代码地址:CSharp_DistributedCache_Simple

  视频演示:Net7_WebAPI分布式缓存中间件DistributedCache

一、目录

缓存类别 Nuget 特性  
Memory内存 Microsoft.Extensions.Caching.Memory(非分布式内存)    
Redis Microsoft.Extensions.Caching.StackExchangeRedis    
SqlServer Microsoft.Extensions.Caching.SqlServer    
NCache NCache.Microsoft.Extensions.Caching.OpenSource    
Mysql Pomelo.Extensions.Caching.MySql    
PostgreSql Community.Microsoft.Extensions.Caching.PostgreSql    

  他们的实现方式基本相同,主要是实现IDistributedCache接口和DistributedCacheExtensions类。可以通过DistributedCacheEntryOptions类配置过期时间等。

二、配置示例

完整的配置代码示例
#define DMemoryCache  // DMemoryCache, MemCached, Redis,NCache, SqlServer, MySql,PostgreSql
using Alachisoft.NCache.Caching.Distributed;
using Alachisoft.NCache.Common.Protobuf;
using Community.Microsoft.Extensions.Caching.PostgreSql;
using Enyim.Caching.Memcached;
using Microsoft.AspNetCore.Http.HttpResults;
using System;
using System.Collections.Generic;
using System.Configuration;

namespace MemoryCache_WebAPI
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.

            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();

            builder.Services.AddMemoryCache(options =>  // 1、内存缓存(一般用于粘性会话或单机缓存;Microsoft.Extensions.Caching.Memory)
            {
                //options.SizeLimit = 100;                                    // 缓存的最大大小为100份
                options.ExpirationScanFrequency = TimeSpan.FromSeconds(2);  // 两秒钟查找一次过期项
                options.CompactionPercentage = 0.2;                         // 缓存满了时候压缩20%的优先级较低的数据
                options.TrackStatistics = false;          // 设置是否跟踪内存缓存统计信息。 默认已禁用
                options.TrackLinkedCacheEntries = false;  // 设置是否跟踪链接条目。 默认已禁用
            });

            #region 分布式内存
#if DMemoryCache
            builder.Services.AddDistributedMemoryCache();  // 2、分布式内存缓存(一般用于分布式会话或分布式内存存储;Microsoft.Extensions.Caching.Memory)
#elif MemCached
            builder.Services.AddEnyimMemcached(options =>  // 2.1 分布式缓存-Memcached (EnyimMemcachedCore)
            {  
                options.AddServer("127.0.0.1", 11211);
            });
#elif Redis
            builder.Services.AddStackExchangeRedisCache(options =>  // 2.2 分布式缓存-Redis (Microsoft.Extensions.Caching.StackExchangeRedis)
            {
                options.Configuration = "127.0.0.1:6379,password=Aa123456,ssl=False,abortConnect=False,defaultDatabase=1";  // 连接字符串;库db1
                //options.InstanceName = "RedisInstance";  // 键值对组(不必须)

                //options.ConfigurationOptions = new StackExchange.Redis.ConfigurationOptions()
                //{
                //    DefaultDatabase = 2,
                //    Password = "12345",  
                //    ConnectTimeout = 5000,   //设置建立连接到Redis服务器的超时时间为5000毫秒
                //    SyncTimeout = 5000,      //设置对Redis服务器进行同步操作的超时时间为5000毫秒
                //    ResponseTimeout = 5000,  //设置对Redis服务器进行操作的响应超时时间为5000毫秒

                //    Ssl = false,  //设置启用SSL安全加密传输Redis数据
                //    //SslHost=""
                //    //SslProtocols = System.Security.Authentication.SslProtocols.Tls//还可以通过SslProtocols属性指定SSL具体用到的是什么协议,不过这个属性不是必须的
                //};
                //options.ConfigurationOptions.EndPoints.Add("192.168.1.105:6379");
            });
#elif NCache
            builder.Services.AddNCacheDistributedCache(options =>  // 2.3 分布式缓存-NCache (NCache.Microsoft.Extensions.Caching.OpenSource)
            {
                options.CacheName = "testcache";  // 缓存名
                options.EnableLogs = true;
                options.ExceptionsEnabled = true;
            });
#elif SqlServer
            builder.Services.AddDistributedSqlServerCache(options =>  // 2.4 分布式缓存-SqlServer (Microsoft.Extensions.Caching.SqlServer)
            {
                options.ConnectionString = "Data Source=(local);Initial Catalog=TestDB;User ID=sa;Password=Aa123456;Persist Security Info=True;Encrypt=True;TrustServerCertificate=True;";  // 连接字符串
                options.SchemaName = "dbo";  // 数据库权限
                options.TableName = "TestCache";  // 表名
                options.DefaultSlidingExpiration = TimeSpan.FromMinutes(20);  // 默认缓存时间
                options.ExpiredItemsDeletionInterval = TimeSpan.FromMinutes(30);  // 过时自动删除

                /* 建表语句如下:
                CREATE TABLE [dbo].[TestCache](
                    [Id] [nvarchar](449) NOT NULL,
                    [Value] [varbinary](max) NOT NULL,
                    [ExpiresAtTime] [datetimeoffset](7) NOT NULL,
                    [SlidingExpirationInSeconds] [bigint] NULL,
                    [AbsoluteExpiration] [datetimeoffset](7) NULL,
                CONSTRAINT [PK_TestCache] PRIMARY KEY CLUSTERED ([Id] ASC)
                WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]) 
                ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]*/
            });
#elif MySql
            builder.Services.AddDistributedMySqlCache(options =>  // 2.5 分布式缓存- MySql (Pomelo.Extensions.Caching.MySql)
            {
                options.ConnectionString = "server=127.0.0.1;uid=root;pwd=Aa123456;database=mysql;port=3306;pooling=false;SslMode=None;old Guids=true;Charset=utf8;AllowUserVariables=true;";  //AllowUserVariables必须加不然会报错
                options.SchemaName = "TestDB";  // 数据库名称
                options.TableName = "testcache";  // 表名
                options.DefaultSlidingExpiration = TimeSpan.FromMinutes(20);  // 默认缓存时间
                options.ExpiredItemsDeletionInterval = TimeSpan.FromMinutes(30);  // 过时自动删除

                /* 建表语句如下:
                CREATE TABLE `testcache` (
                  `Id` varchar(449) CHARACTER SET utf8 NOT NULL,
                  `Value` longblob NOT NULL,
                  `ExpiresAtTime` datetime NOT NULL,
                  `SlidingExpirationInSeconds` bigint(20) DEFAULT NULL,
                  `AbsoluteExpiration` datetime DEFAULT NULL,
                  PRIMARY KEY (`Id`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='缓存存储表'*/
            });
#elif PostgreSql
            builder.Services.AddDistributedPostgreSqlCache(options =>  // 2.6 分布式缓存- PostgreSql (Community.Microsoft.Extensions.Caching.PostgreSql)
            {
                options.ConnectionString = "host=127.0.0.1;Port=5432;database=testdb;username=root;password=Aa123456;";  // HOST=localhost;PORT=5432;DATABASE=testdb;USER ID=root;PASSWORD=Aa123456;
                options.SchemaName = "TestDB";  // 数据库名称
                options.TableName = "testcache";  //表名
                options.DefaultSlidingExpiration = TimeSpan.FromMinutes(20);  // 默认过期时间
                options.ExpiredItemsDeletionInterval = TimeSpan.FromMinutes(30);  //过时自动删除
            });
#endif
            #endregion 分布式内存

            builder.Services.AddOutputCache();      // 3、其他缓存-输出缓存中间件
            builder.Services.AddResponseCaching();  // 4、其他缓存-响应缓存中间件

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }

            //#if MemCached
            //            app.UseEnyimMemcached();  // 可以注释掉这里;因为默认已调用了app.UseDefaultMemcached();
            //#endif

            app.UseAuthorization();

            app.UseOutputCache();      // 启用其他缓存-输出缓存
            app.UseResponseCaching();  // 启用其他缓存-响应缓存

            app.MapControllers();

            app.Run();
        }
    }
}

1、MemoryCache内存缓存(伪分布式;builder.Services.AddDistributedMemoryCache();)

  builder.Services.AddDistributedMemoryCache();  // 2、分布式内存缓存(一般用于分布式会话或分布式内存存储;Microsoft.Extensions.Caching.Memory)

  注:这是用的是builder.Services.AddDistributedMemoryCache()builder.Services.AddMemoryCache()的用法见《C#-缓存(一)_内存缓存MemoryCache》。

2、Memcached

  builder.Services.AddEnyimMemcached(options => {  // 2.1 分布式缓存-Memcached (EnyimMemcachedCore)
      options.AddServer("127.0.0.1", 11211);
  });

3、Redis

  builder.Services.AddStackExchangeRedisCache(options =>  // 2.2 分布式缓存-Redis (Microsoft.Extensions.Caching.StackExchangeRedis)
  {
      options.Configuration = "127.0.0.1:6379,password=Aa123456,ssl=False,abortConnect=False,defaultDatabase=1";  // 连接字符串;库db1
      //options.InstanceName = "RedisInstance";  // 键值对组(选填)
 
      //options.ConfigurationOptions = new StackExchange.Redis.ConfigurationOptions()
      //{
      //    DefaultDatabase = 2,
      //    Password = "12345",  
      //    ConnectTimeout = 5000,   //设置建立连接到Redis服务器的超时时间为5000毫秒
      //    SyncTimeout = 5000,      //设置对Redis服务器进行同步操作的超时时间为5000毫秒
      //    ResponseTimeout = 5000,  //设置对Redis服务器进行操作的响应超时时间为5000毫秒
 
      //    Ssl = false,  //设置启用SSL安全加密传输Redis数据
      //    //SslHost=""
      //    //SslProtocols = System.Security.Authentication.SslProtocols.Tls//还可以通过SslProtocols属性指定SSL具体用到的是什么协议,不过这个属性不是必须的
      //};
      //options.ConfigurationOptions.EndPoints.Add("192.168.1.105:6379");
  });

4、NCache

  builder.Services.AddNCacheDistributedCache(options =>  // 2.3 分布式缓存-NCache (NCache.Microsoft.Extensions.Caching.OpenSource)
  {
      options.CacheName = "testcache";  // 缓存名
      options.EnableLogs = true;
      options.ExceptionsEnabled = true;
  });

5、SqlServer

  builder.Services.AddDistributedSqlServerCache(options =>  // 2.4 分布式缓存-SqlServer (Microsoft.Extensions.Caching.SqlServer)
  {
      options.ConnectionString = "Data Source=(local);Initial Catalog=TestDB;User ID=sa;Password=Aa123456;Persist Security Info=True;Encrypt=True;TrustServerCertificate=True;";  // 连接字符串
      options.SchemaName = "dbo";  // 数据库权限
      options.TableName = "TestCache";  // 表名
      options.DefaultSlidingExpiration = TimeSpan.FromMinutes(20);  // 默认缓存时间
      options.ExpiredItemsDeletionInterval = TimeSpan.FromMinutes(30);  // 过时自动删除

      /* SqlServer需要提前创建表,建表语句如下:
      CREATE TABLE [dbo].[TestCache](
          [Id] [nvarchar](449) NOT NULL,
          [Value] [varbinary](max) NOT NULL,
          [ExpiresAtTime] [datetimeoffset](7) NOT NULL,
          [SlidingExpirationInSeconds] [bigint] NULL,
          [AbsoluteExpiration] [datetimeoffset](7) NULL,
      CONSTRAINT [PK_TestCache] PRIMARY KEY CLUSTERED ([Id] ASC)
      WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]) 
      ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]*/
  });

6、Mysql

  builder.Services.AddDistributedMySqlCache(options =>  // 2.5 分布式缓存- MySql (Pomelo.Extensions.Caching.MySql)
  {
      options.ConnectionString = "server=127.0.0.1;uid=root;pwd=Aa123456;database=mysql;port=3306;pooling=false;SslMode=None;old Guids=true;Charset=utf8;AllowUserVariables=true;";  //AllowUserVariables必须加不然会报错
      options.SchemaName = "TestDB";  // 数据库名称
      options.TableName = "testcache";  // 表名
      options.DefaultSlidingExpiration = TimeSpan.FromMinutes(20);  // 默认缓存时间
      options.ExpiredItemsDeletionInterval = TimeSpan.FromMinutes(30);  // 过时自动删除

      /* Mysql需要提前创建表,建表语句如下:
      CREATE TABLE `testcache` (
        `Id` varchar(449) CHARACTER SET utf8 NOT NULL,
        `Value` longblob NOT NULL,
        `ExpiresAtTime` datetime NOT NULL,
        `SlidingExpirationInSeconds` bigint(20) DEFAULT NULL,
        `AbsoluteExpiration` datetime DEFAULT NULL,
        PRIMARY KEY (`Id`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='缓存存储表'*/
  });

7、PostgreSql

  builder.Services.AddDistributedPostgreSqlCache(options =>  // 2.6 分布式缓存- PostgreSql (Community.Microsoft.Extensions.Caching.PostgreSql)
  {
      options.ConnectionString = "host=127.0.0.1;Port=5432;database=testdb;username=root;password=Aa123456;";  // HOST=localhost;PORT=5432;DATABASE=testdb;USER ID=root;PASSWORD=Aa123456;
      options.SchemaName = "TestDB";  // 数据库名称
      options.TableName = "testcache";  //表名
      options.DefaultSlidingExpiration = TimeSpan.FromMinutes(20);  // 默认过期时间
      options.ExpiredItemsDeletionInterval = TimeSpan.FromMinutes(30);  //过时自动删除
  });

三、缓存使用示例

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using System.Text;

namespace MemoryCache_WebAPI.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class DistributedMemoryCacheController : ControllerBase
    {
        #region 变量
        /// <summary>
        /// 日志
        /// </summary>
        private readonly ILogger<DistributedMemoryCacheController> _logger;

        /// <summary>
        /// 分布式内存缓存
        /// </summary>
        private readonly IDistributedCache _cache;

        private static string[] Summaries = new[]
        {
            "空"
        };
        #endregion 变量

        /// <summary>
        /// 
        /// </summary>
        public DistributedMemoryCacheController(ILogger<DistributedMemoryCacheController> logger, IDistributedCache cache)
        {
            _logger = logger;
            _cache = cache;
        }

        [HttpGet(Name = "DistributedMemoryCacheTest")]
        public IEnumerable<WeatherForecast> Get()
        {
            #region 取值
            Summaries[0] = "空";

            var encodedCachedTimeUTC = _cache.Get("cachedTimeUTC");  // 取值
            if (encodedCachedTimeUTC != null)
            {
                string cachedTimeUTC = Encoding.UTF8.GetString(encodedCachedTimeUTC);  // 转
                Summaries[0] = cachedTimeUTC ?? "";
            }
            #endregion 取值

            #region 重置过期时间的方法
            _cache.Refresh("cachedTimeUTC");
            #endregion 重置过期时间的方法

            return Summaries.Select(a => new WeatherForecast()
            {
                Date = DateOnly.FromDateTime(DateTime.Now),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = a
            });
        }

        [HttpPut(Name = "DistributedMemoryCacheTest_Set")]
        public bool Set()
        {
            #region 存值
            var currentTimeUTC = DateTime.UtcNow.ToString();  // 当前时间
            byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);  // 转Byte

            var options = new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(30));  // 设置过期时间
            _cache.Set("cachedTimeUTC", encodedCurrentTimeUTC, options);  // 存值
            #endregion 存值

            return true;
        }

        [HttpDelete(Name = "DistributedMemoryCacheTest_Delete")]
        public bool Detele()
        {
            #region 删除值
            _cache.Remove("cachedTimeUTC");
            #endregion 删除值
            return true;
        }
    }
}

 

posted @   ꧁执笔小白꧂  阅读(420)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示