讲师中心 微信公众号
AI工具推荐 视频效率加速

c# 高并发下的缓存预热和数据同步方案

老丽大大_7902

老丽大大_7902

发布时间:2026-01-12 10:39:11

|

676人浏览过

|

来源于php中文网

原创

缓存预热需在应用启动后、首个请求前同步完成,避免缓存击穿;分布式环境必须使用带版本号的 IDistributedCache 并禁用滑动过期;数据更新须执行“删-更-延时再删”三步法,并用 SemaphoreSlim 控制并发重建。

c# 高并发下的缓存预热和数据同步方案

缓存预热必须在应用启动后、首个请求前完成

高并发下,如果等第一个请求触发缓存加载,必然导致大量线程争抢初始化(即“缓存击穿”),尤其当 GetOrAdd 用的是非线程安全的工厂函数时,可能重复执行耗时操作。正确做法是:在 Program.cs 或 Startup.ConfigureServices 中显式调用预热逻辑,并确保其同步阻塞到完成。

  • 使用 Task.Run(() => PreheatCache()).Wait() 强制同步等待(注意不要在 ASP.NET Core 的同步上下文里用 .Result,易死锁)
  • 预热函数内部应避免依赖 IHttpContextAccessor 等请求作用域服务;改用 IServiceScopeFactory 创建独立 scope
  • 若预热数据量大,可分批 + await Task.Delay(1) 防止单次占用主线程太久,但整体仍需在 WebApplication 构建完成前结束

分布式环境必须用带版本号的缓存键 + 原子写入

单机 MemoryCache 在多实例部署下完全失效。必须切换为 IDistributedCache(如 Redis),且不能直接存原始对象——否则多个节点同时更新会覆盖彼此,造成脏数据。

Web Accessibility (WCAG 2 AA))
Web Accessibility (WCAG 2 AA))

将 WCAG 2 AA 无障碍标准应用于设计系统、UI 组件和网页——通过可运行的验证器进行对比度计算,采用设计 token 模式使颜色天生可访问,设定排版和焦点状态规则,并提供语义检查清单。适用于构建或审查 UI。

下载
  • 缓存键格式建议为:$"user:profile:v2:{userId}",其中 v2 是业务版本号,每次数据结构变更就升级,强制全量刷新
  • 写入时用 distributedCache.SetStringAsync(key, json, new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(2) }),禁用滑动过期(SlidingExpiration),防止“越用越旧”
  • 关键数据更新后,必须同步调用 distributedCache.RemoveAsync(key),而不是等过期;删除失败要记录告警,不可静默忽略

数据库与缓存一致性靠“先删缓存,再更DB”+ 延迟双删兜底

“先更DB,再删缓存”在并发更新时有概率导致缓存残留旧值(DB 更新成功,但删缓存失败或被覆盖)。生产环境必须用“删除-更新-延迟再删”三步法。

  • 第一步:调用 distributedCache.RemoveAsync(key)
  • 第二步:执行 EF Core 的 SaveChangesAsync()
  • 第三步:启动后台任务,await Task.Delay(TimeSpan.FromSeconds(500)) 后再次 RemoveAsync(key) —— 覆盖因主从延迟、重试机制导致的缓存回写
  • 所有删缓存操作必须包裹 try/catch,失败时写入本地队列(如 ConcurrentQueue),由后台服务重试,不能丢弃

并发读场景下避免 Cache Stampede,用 SemaphoreSlim 限流重建

即使做了预热,缓存过期瞬间仍可能有上百请求同时发现缓存为空,全部涌入 DB。不能靠 GetOrCreateAsync 默认行为扛住——它的 factory 函数不是原子的。

  • 为每个缓存键维护一个 ConcurrentDictionary<string semaphoreslim></string>,键为 cache key,值为独占信号量
  • 读取时:先 cache.TryGetValue(key, out var value);若为空,则 semaphores.GetOrAdd(key, _ => new SemaphoreSlim(1,1)).WaitAsync()
  • 获得信号量后,再次检查缓存(double-check),未命中才重建;完成后 Release() 并移除该 semaphore(避免内存泄漏)
  • 注意:不要用 lock,它跨进程无效;也不要复用同一个 SemaphoreSlim 实例,会导致不同 key 互相阻塞
private static readonly ConcurrentDictionary<string, SemaphoreSlim> _semaphores = new();
public async Task<UserProfile> GetProfileAsync(int userId)
{
    var key = $"user:profile:v2:{userId}";
    if (_cache.TryGetValue(key, out UserProfile profile))
        return profile;

    var semaphore = _semaphores.GetOrAdd(key, _ => new SemaphoreSlim(1, 1));
    await semaphore.WaitAsync();
    try
    {
        // Double-check after acquiring semaphore
        if (_cache.TryGetValue(key, out profile))
            return profile;

        profile = await _db.Users.FirstAsync(u => u.Id == userId);
        await _cache.SetStringAsync(key, JsonSerializer.Serialize(profile), 
            new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30) });
        return profile;
    }
    finally
    {
        semaphore.Release();
        _semaphores.TryRemove(key, out _);
    }
}
缓存键设计、删除时机、并发重建这三点一旦漏掉任意一个,高并发下的数据不一致就会变成偶发性线上事故——而这类问题往往在压测时不出,上线后半夜爆发。

热门AI工具

更多
AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

超级麦吉

一款通过数字员工协作完成调研、数据分析与文档制作的AI办公平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

相关专题

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

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

2093

2023.08.11

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

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

3314

2023.10.07

json数据格式
json数据格式

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

2195

2023.08.07

json是什么
json是什么

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

3462

2023.08.23

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

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

1156

2023.10.13

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

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

3979

2025.09.10

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

4208

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

804

2025.10.23

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

20

2026.10.28

热门下载

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

精品课程

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

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn