.Net C# MemoryCache 缓存

缓存是一种开发时常用的性能优化手段,.Net自带内存缓存(MemoryCache)可以很方便的使用,下面列出简单用法。

首先通过NuGet添加 Microsoft.Extensions.Hosting、Microsoft.Extensions.Caching.Memory 这两个包。

添加命令:

Install-Package Microsoft.Extensions.Caching.Memory

Install-Package Microsoft.Extensions.Hosting

向缓存中添加数据:

memoryCache.Set(dog.Name, dog, options);

从缓存获取数据(可以直接使用泛型方法指定返回类型):

memoryCache.Get(key);

添加时可以使用 await memoryCache.GetOrCreateAsync()方法完成,该方法可以在缓存中没有数据时另外处理获取数据的方式,并将结果添加进缓存中。

参考代码:

internal class CacheDemo
    {
        //该集合当做数据源
        static IEnumerable dogs;
        //全局容器
        static IHost host;
        public static async Task DemoMain()
        {
            //向容器添加缓存服务
            host = Host.CreateDefaultBuilder()
                .ConfigureServices(services => services.AddMemoryCache())
                .Build();

            //向数据源填充数据
            dogs = GetDogs().ToList();
            //缓存配置
            MemoryCacheEntryOptions cacheOptions = new()
            {
                //设置缓存10秒过期
                AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(10)
            };



            //循环查询缓存中是否有对应数据
            foreach (Dog dog in GetDogs())
            {
                var dogResult = await GetDogAsync(dog.Name);
                Console.WriteLine($"查询结果1:{dogResult}");
            }

            var dogResult2 = GetCacheData("泰迪");
            Console.WriteLine($"查询结果2:{dogResult2}");
            Console.WriteLine("等待11秒缓存过期后再获取");
            await Task.Delay(11000);
            var dogResult3 = GetCacheData("泰迪");
            Console.WriteLine($"查询结果3:{dogResult3}");
            //向缓存中添加泰迪
            SetCacheData(new Dog("泰迪", 1), cacheOptions);
            var dogResult4 = GetCacheData("泰迪");
            Console.WriteLine($"查询结果4:{dogResult4}");
            var dogResult5 = GetCacheData("吉娃娃");
            Console.WriteLine($"查询结果5:{dogResult5}");

        }
        /// 
        /// 从缓存中获取数据
        /// 如果没有则从数据源获取并添加至缓存
        /// 
        /// 
        /// 
        private static async Task GetDogAsync(string name)
        {
            //从容器中获取缓存服务
            IMemoryCache memoryCache = host.Services.GetRequiredService();

            //查询缓存数据,没有则从数据源查询并添加至缓存
            var dogResult = await memoryCache.GetOrCreateAsync(name, t =>
            {
                t.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(10);
                Console.WriteLine($"缓存中没有{name},查询集合数据!");
                Dog dog1 = dogs.SingleOrDefault(d => d.Name.Equals(name));
                return Task.FromResult(dog1);
            });

            return dogResult;
        }
        /// 
        /// 向缓存中添加数据
        /// 
        /// 
        /// 
        private static void SetCacheData(Dog dog, MemoryCacheEntryOptions options)
        {
            //从容器中获取缓存服务
            IMemoryCache memoryCache = host.Services.GetRequiredService();

            memoryCache.Set(dog.Name, dog, options);
        }
        /// 
        /// 缓存中获取数据
        /// 
        /// 
        /// 
        private static Dog GetCacheData(string key)
        {
            //从容器中获取缓存服务
            IMemoryCache memoryCache = host.Services.GetRequiredService();

            return memoryCache.Get(key);
        }

        /// 
        /// 获取所有可爱的狗
        /// 
        /// 
        private static IEnumerable GetDogs()
        {
            yield return new Dog("泰迪", 1);
            yield return new Dog("吉娃娃", 2);
            yield return new Dog("哈士奇", 3);
            yield return new Dog("罗威纳", 4);
        }
    }
    /// 
    /// 狗类
    /// 
    /// 
    /// 
    internal record Dog(string Name, int Id);

输出结果:

.Net C# MemoryCache 缓存_第1张图片

缓存雪崩:是指同一时间大量缓存失效, 导致大量请求发向后端服务。

向缓存添加数据时,时间可以设置一定范围的随机时间,这是一种避免出现缓存雪崩的简单方法。

缓存击穿:是指热点缓存失效,导致查询该热点数据的请求大量查询后端服务。

如果业务场景允许,可以每次延长缓存时间或者设置为不过期。也可以使用单独的任务来维护热点数据缓存。

缓存穿透:是指大量不存在的数据请求(比如恶意请求)进行查询,此时缓存和后端服务中都没有这些数据,浪费大量资源。

这个时候使用布隆过滤器是个很好的选择。

你可能感兴趣的:(.Net,C#,.net,c#,缓存,microsoft)