Distributed Cache(分布式缓存)-Redis

Net Core 缓存系列:

    1、NetCore IMemoryCache 内存缓存

    2、Distributed Cache(分布式缓存)-SqlServer

    3、Distributed Cache(分布式缓存)-Redis

欢迎交流学习!!! GitHub源码

Asp.NET Core 官网目前支持的分布式缓存主要有Sql Server, Redis 和NCache,Sql Server的分布式安装及使用已在上篇文章记录 Distributed Cache(分布式缓存)-SqlServer ,NCache会在接下里的文章中提及。

Redis使用

1、将redis service 添加到Services请求管道中:

 services.AddDistributedRedisCache(options =>
 {
       options.Configuration = $"{configuration["RedisDistributedCache:IPAddress"]}:{configuration["RedisDistributedCache:Port"]},password={configuration["RedisDistributedCache:Password"]}";
       options.InstanceName = configuration["RedisDistributedCache:InstanceName"];
 });

appsettings.json配置文件如下:

"RedisDistributedCache": {
    "IPAddress": "127.0.0.1",
    "Port": "6379",
    "Password": "demo12!@",
    "InstanceName": "DistributedCache.Redis"
  }

2、根据业务需要封装IDistributedCache service,当然这里完全可以使用原生IDistributedCache, 直接通过构造函数依赖注入即可用。

提供必要的SetAsync / GetAsync接口实现,示例代码如下:

    public class RedisService : IDistributedService
    {
        private readonly IDistributedCache _cacheService;

        public RedisService(IDistributedCache cacheService)
        {
            this._cacheService = cacheService;
        }

        public async Task<T> GetAsync<T>(string key)
        {
            T obj = default(T);
            var value = await _cacheService.GetStringAsync(key);
            if (string.IsNullOrEmpty(value))
            { 
                return default(T);
            }
            try
            {
                obj = JsonConvert.DeserializeObject<T>(value);
            }
            catch (Exception ex)
            {
                throw new NotSupportedException(ex.Message, ex);
            }
            return obj;
        }

        public async Task<byte[]> GetAsync(string key)
        {
            return await _cacheService.GetAsync(key);
        }

        public async Task<string> GetStringAsync(string key)
        {
            return await _cacheService.GetStringAsync(key);
        }

        public async Task RefreshAsync(string key)
        {
            await _cacheService.RefreshAsync(key);
        }

        public async Task RemoveAsync(string key)
        {
            await _cacheService.RemoveAsync(key);
        }

        public async Task SetAsync(string key, object value, object expiration = null, bool isAbsoluteExpiration = false)
        {
            var jsonValue = string.Empty;
            try
            {
                jsonValue = JsonConvert.SerializeObject(value);
                var options = this.BuildDistributedCacheEntryOptions(expiration, isAbsoluteExpiration);
                await _cacheService.SetStringAsync(key, jsonValue, options);
            }
            catch (Exception ex)
            {
                throw new NotSupportedException(ex.Message, ex);
            }
        }

        public async Task SetAsync(string key, byte[] value, object expiration = null, bool isAbsoluteExpiration = false)
        {
            var options = this.BuildDistributedCacheEntryOptions(expiration, isAbsoluteExpiration);
            await _cacheService.SetAsync(key, value, options);
        }

        private DistributedCacheEntryOptions BuildDistributedCacheEntryOptions(object expiration = null, bool isAbsoluteExpiration = false)
        {
            var options = new DistributedCacheEntryOptions();
            if (expiration != null)
            {
                if (expiration is TimeSpan)
                {
                    if (isAbsoluteExpiration)
                        options.SetAbsoluteExpiration((TimeSpan)expiration);
                    else
                        options.SetSlidingExpiration((TimeSpan)expiration);
                }
                else if (expiration is DateTimeOffset)
                {
                    options.SetAbsoluteExpiration((DateTimeOffset)expiration);
                }
                else
                {
                    throw new NotSupportedException("Not support current expiration object settings.");
                }
            }
            return options;
        }
    }
View Code

3、将自定义的Redis service添加到Services请求管道中,因为项目中SqlServerService及RedisService均实现了同一个接口IDistributedService,因此向请求管道添加Services的方式有所不同,通过传入的CacheType动态获取相应的Service方法。示例如下:

 services.AddTransient<SqlServerService>();
 services.AddTransient<RedisService>();
 services.AddSingleton(provider =>
 {
                Func<CacheType, IDistributedService> func = type =>
                {
                    switch (type)
                    {
                        case CacheType.SQL:
                            return provider.GetService<SqlServerService>();
                        case CacheType.Redis:
                            return provider.GetService<RedisService>();
                        default:
                            throw new NotSupportedException();
                    }
                };
                return func;
  });

4、Console中测试如下:

static void Main(string[] args)
{
            var services = new ServiceCollection();
            services.ConfigureServices();

            var serviceProvider = services.BuildServiceProvider();
            var cacheService = (RedisService)serviceProvider.GetService(typeof(RedisService));

            cacheService.SetAsync("key01", "value01").GetAwaiter().GetResult();
            var cacheValue = cacheService.GetStringAsync("key01").GetAwaiter().GetResult();
    
            Console.ReadKey();
}
View Code

5、通过Redis-desktop-Manager查看结果:

 

 OK,Redis的Distributed Cache的使用介绍到这里。

 

接下来花费一些篇幅介绍下Redis的配置及安装,供大家参考。

Redis-desktop-Manager 

下载地址:https://github.com/uglide/RedisDesktopManager/releases/tag/0.8.8

Redis的安装

Redis官网不建议windows下使用Redis,所有官网没有windows版本下载。幸运的是微软团队维护了开源的windows版本,虽然只有3.2版本,对于我们测试学习来说足够用了,感谢,感谢!

下载地址:https://github.com/microsoftarchive/redis/releases  这里提供了2种包的安装方式,Redis-x64-3.2.100.msi 及 Redis-x64-3.2.100.zip,根据自己的需求哪种都可以。

 1、第一种方式:下载 Redis-x64-3.2.100.msi 安装,Next, 有几个特殊设置注意一下即可。

 1)、勾选 Add the Redis installation folder to the PATH enviroment variable (添加到path是把redis设置成windows下的服务,不然每次使用redis都需要命令行启动redis-server redis.windows.conf, 命令行窗口关闭,redis服务停止)

  2)、勾选Add an exception to the windows Firewall, 并且设置端口号,这里默认是6379

3)、设置最大内存(options)

如果redis当做db使用,建议不要设置这个值;如果是作为cache缓存,根据需要设置Redis最大内存限制,达到最大内存后,Redis会先尝试清除已到期或者即将到期的key,如果仍达到最大内存设置,将无法进行写入操作,但可以进行读取。Redis新的VM机制,会把key存放在内存中,value存放在swap区。

 4)、安装完成之后win+r 输入services.msc打开services,查看Redis是否安装成功及启用

 2、第二种方式:下载Redis-x64-3.2.100.zip 直接解压安装,一路Next即可。

安装完成后,打开安装目录

 文件解释:

edis-server.exe:服务端程序,提供 redis 服务

redis-cli.exe: 客户端程序,通过它连接 redis 服务并进行操作

redis-check-dump.exe:RDB 文件修复工具

redis-check-aof.exe:AOF 文件修复工具

redis-benchmark.exe:性能测试工具,用以模拟同时由 N 个客户端发送 M 个 SETs/GETs 查询 (类似于 Apache 的 ab 工具)

redis.windows.conf: 配置文件,将 redis 作为普通软件使用的配置,命令行关闭则 redis 关闭

redis.windows-service.conf:配置文件,将 redis 作为系统服务的配置

 启动Redis服务,启动cmd cd到安装目录,执行:

redis-server.exe redis.windows.conf 

输出如下:

 

 

 添加redis service到windows services中:

redis-server --service-install redis.windows.conf

启动redis服务:

redis-server --service-start

停止redis服务:

redis-server --service-stop

Notes:

  1、如果在执行cmd命令时出现错误代码为18012的错误,表示本机端口6379被占用,换个端口即可。

 

Windows redis service 配置

 1、默认安装redis之后,访问redis service是不需要密码的,可以修改redis.windows-service.conf文件在requirepass下添加一行requirepass ***。

 2、配置成外网可访问的redis service,修改redis.windows-service.conf 及redis.windows.confi文件:

   1)、注释掉 #bind 127.0.0.1

    2)、修改protected-mode: no

 

posted @ 2021-03-14 10:45  云霄宇霁  阅读(4912)  评论(0编辑  收藏  举报