C#如何实现缓存策略?内存缓存(MemoryCache)与分布式缓存(Redis)实战

老丽君_6200

老丽君_6200

2025-11-24

1043人浏览

原创

答案:c#中通过memorycache实现本地缓存、redis实现分布式缓存,结合缓存穿透、击穿、雪崩防护策略及双写一致性设计,提升系统性能。

c#如何实现缓存策略?内存缓存(memorycache)与分布式缓存(redis)实战

在C#开发中,缓存是提升系统性能的关键手段。合理使用缓存可以减少数据库压力、加快响应速度。常见的缓存策略主要分为两类:内存缓存和分布式缓存。下面结合实战讲解如何在.NET项目中使用 MemoryCache 和 Redis 实现高效的缓存机制。

1. 内存缓存 MemoryCache 的使用

MemoryCache 是 .NET 提供的本地内存缓存实现,适用于单机部署场景,读写速度快,但不具备进程间共享能力。

基本用法:

  • 通过 NuGet 安装 Microsoft.Extensions.Caching.Memory 包。
  • 在 Program.cs 或 Startup.cs 中注册服务:
builder.Services.AddMemoryCache();

创建一个缓存服务类:

public class InMemoryCacheService
{
    private readonly IMemoryCache _cache;

    public InMemoryCacheService(IMemoryCache cache)
    {
        _cache = cache;
    }

    public T GetOrCreate(string key, Func factory)
    {
        return _cache.GetOrCreate(key, factory);
    }

    public void Remove(string key)
    {
        _cache.Remove(key);
    }
}

使用示例:缓存用户数据

var user = _memoryCache.GetOrCreate("user_123", entry =>
{
    entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10);
    return _userRepository.GetById(123);
});

支持设置过期时间(绝对或滑动)、优先级、回调等策略。

2. 分布式缓存 Redis 的集成

当应用部署在多个实例或需要共享状态时,Redis 是更合适的选择。它支持高并发、持久化和跨服务器共享缓存。

redis-tools
redis-tools

按类别查找Redis命令、检测服务器连接、监控键数量和内存占用,支持离线速查表。

下载

集成步骤:

  • 安装 StackExchange.Redis 或使用 Microsoft.Extensions.Caching.StackExchangeRedis。
  • 在 Program.cs 中添加 Redis 缓存:
builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = "localhost:6379";
    options.InstanceName = "sample_";
});

注入 IDistributedCache 接口进行操作:

public class RedisCacheService
{
    private readonly IDistributedCache _cache;

    public RedisCacheService(IDistributedCache cache)
    {
        _cache = cache;
    }

    public async Task GetStringAsync(string key)
    {
        return await _cache.GetStringAsync(key);
    }

    public async Task SetStringAsync(string key, string value, TimeSpan? expiry = null)
    {
        await _cache.SetStringAsync(key, value, new DistributedCacheEntryOptions
        {
            AbsoluteExpirationRelativeToNow = expiry ?? TimeSpan.FromMinutes(20)
        });
    }
}

对于复杂对象,可结合 System.Text.Json 序列化存储:

public async Task SetObjectAsync(string key, T value, TimeSpan? expiry = null)
{
    var json = JsonSerializer.Serialize(value);
    await _cache.SetStringAsync(key, json, new DistributedCacheEntryOptions
    {
        AbsoluteExpirationRelativeToNow = expiry
    });
}

public async Task GetObjectAsync(string key)
{
    var json = await _cache.GetStringAsync(key);
    return json == null ? default : JsonSerializer.Deserialize(json);
}

3. 缓存策略设计建议

实际项目中应根据业务需求选择合适的缓存层级与更新机制。

  • 缓存穿透:对不存在的数据做空值缓存,并设置较短过期时间。
  • 缓存击穿:热点数据过期时可能引发大量请求打到数据库,可用互斥锁(如 Redis 的 SETNX)控制重建。
  • 缓存雪崩:避免大量缓存同时失效,可为过期时间增加随机偏移。
  • 双写一致性:更新数据库后及时清除或更新缓存,推荐“先更新 DB,再删缓存”策略。

可封装通用缓存接口,支持运行时切换实现:

public interface IAppCache
{
    Task GetOrCreateAsync(string key, Func> factory, TimeSpan? expiry = null);
    Task RemoveAsync(string key);
}

分别用 MemoryCache 和 Redis 实现该接口,便于后期扩展。

基本上就这些。MemoryCache 简单高效,适合本地缓存;Redis 功能强大,支撑分布式架构。根据场景灵活选择,才能发挥最大价值。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
什么是分布式
什么是分布式

分布式是一种计算和数据处理的方式,将计算任务或数据分散到多个计算机或节点中进行处理。本专题为大家提供分布式相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2073

5

分布式和微服务的区别
分布式和微服务的区别

分布式和微服务的区别在定义和概念、设计思想、粒度和复杂性、服务边界和自治性、技术栈和部署方式等。本专题为大家提供分布式和微服务相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.07

3214

5

json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2023.08.07

2155

5

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.23

3342

1

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

2023.10.13

1116

3

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

2025.09.10

3839

7

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

6559

3

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

2023.09.22

549

3

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

2024.03.01

1698

6

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
phpEnv手册
phpEnv手册

共0课时 | 0人学习