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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM