下面是一个标准的IDistributedCache用例:

public class SomeService(IDistributedCache cache)
{
public async Task<SomeInformation> GetSomeInformationAsync
(string name, int id, CancellationToken token = default)
{
var key = $"someinfo:{name}:{id}"; // Unique key for this combination.
var bytes = await cache.GetAsync(key, token); // Try to get from cache.
SomeInformation info;
if (bytes is null)
{
// Cache miss; get the data from the real source.
info = await SomeExpensiveOperationAsync(name, id, token); // Serialize and cache it.
bytes = SomeSerializer.Serialize(info);
await cache.SetAsync(key, bytes, token);
}
else
{
// Cache hit; deserialize it.
info = SomeSerializer.Deserialize<SomeInformation>(bytes);
}
return info;
} // This is the work we're trying to cache.
private async Task<SomeInformation> SomeExpensiveOperationAsync(string name, int id,
CancellationToken token = default)
{ /* ... */ }
}

在这个用例中 每次都要做很多事情,包括序列化/反序列化。如果缓存不存在/未命中,可能会有多个并发线程获取基础数据并序列化数据,并将所有数据推送到缓存中间件中,我们看到这里 分布式缓存使用上就没有IMemoryCache那么性能高效, 为此.NET团队在NET9中 添加了 HybridCache解决这个痛点,

原理还是简单,使用本地的IMemoryCacheIDistributedCache包装一层提供一个二级缓存包装的概念.

下面简单引用一下:

<PackageReference Include="Microsoft.Extensions.Caching.Hybrid" Version="9.0.0" />
services.AddMemoryCache();
services.AddDistributedMemoryCache();//分布式缓存这里默认本地内存缓存,可以是Redis等~
services.AddHybridCache(options =>
{
//options.MaximumPayloadBytes = 1*1024*1024 //默认超过1M的数据不会提供本地二级缓存,避免应用服务器内存负担
options.DefaultEntryOptions = new HybridCacheEntryOptions{
Expiration = TimeSpan.FromSeconds(5 * 60),//设置一个分布式缓存默认过期时间
LocalCacheExpiration = TimeSpan.FromSeconds(5 * 60 - 1)//本地二级缓存默认过期时间,比前者短就行.或者你认为可以接受的范围.
};
});

/// <summary>
/// 模拟的缓存数据类型
/// </summary>
public record CacheData(DateTime? DateTime); //NET8中的IDistributedCache
x.MapGet("/cached-in-distribute", async (IDistributedCache distributedCache) =>
{
if (await distributedCache.GetStringAsync("$cached-in-distribute") is null)
{
var data = System.Text.Json.JsonSerializer.Serialize(new CacheData(DateTime.Now));
await distributedCache.SetStringAsync("$cached-in-distribute", data, new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(10d)
});
} var fromCacheData = System.Text.Json.JsonSerializer.Deserialize<CacheData>(
await distributedCache.GetStringAsync("$cached-in-distribute") ?? throw new Exception());
return Results.Content($"{fromCacheData?.DateTime}-{DateTime.Now}");
}); //NET9 HybridCache,避免分布式缓存的强制转换
x.MapGet("/cached-in-hybrid", async (HybridCache hybridCache) =>
{
var cachedDate = await hybridCache.GetOrCreateAsync($"$cached-in-hybrid", async cancel =>
{
return await ValueTask.FromResult(new CacheData(DateTime.Now));
}, options: new HybridCacheEntryOptions
{
Expiration = TimeSpan.FromSeconds(10d),//便于验证,设直10秒过期
LocalCacheExpiration = TimeSpan.FromSeconds(10d),
});
return Results.Content($"缓存的数据:{cachedDate.DateTime}");
});

HybridCache通过本地的二级缓存避免了频繁的与分布式缓存服务器的交互以及成本高昂的类型转换(如果数据结构复杂庞大更甚)性能瞬间又提升了.

另外HybridCache是一个抽象类,微软默认的实现是二级到内存缓存,如果你有兴趣甚至可以无限封装扩展到其他的缓存中 比如你自己的YourHybridCache

services.TryAddSingleton<HybridCache, YourHybridCache>();

最后Microsoft.Extensions.Caching.Hybrid兼容.NET Framework 4.7.2 and .NET Standard 2.0这个也可以点个赞,对老系统升级比较友好!

更多信息:

https://learn.microsoft.com/en-us/aspnet/core/performance/caching/hybrid?view=aspnetcore-9.0

用例代码:

https://github.com/vipwan/Biwen.QuickApi/blob/net9/Biwen.QuickApi.DemoWeb/~DemoModular.cs

NET9 提供HybridCache解决分布式缓存中存在的远程链接&序列化带来的性能问题的更多相关文章

  1. 分布式理论(4):Leases 一种解决分布式缓存一致性的高效容错机制(转)

    作者:Cary G.Gray and David R. Cheriton 1989 译者:phylips@bmy 2011-5-7 出处:http://duanple.blog.163.com/blo ...

  2. 解决 分布式事务中HRESULT:0x8004D025 错误

    最近在开发分布式事务的过程中,碰到 该伙伴事务管理器已经禁止了它对远程/网络事务的支持. (异常来自 HRESULT:0x8004D025)的错误. 后来检查到,原来是数据库服务器的MSDTC 没有设 ...

  3. Window平台搭建Redis分布式缓存集群 (一)server搭建及性能測试

    百度定义:Redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对很多其它.包含string(字符串).list(链表).set(集合).zset(sort ...

  4. 彻底解决Spring mvc中时间的转换和序列化等问题

    痛点 在使用Spring mvc 进行开发时我们经常遇到前端传来的某种格式的时间字符串无法用java8的新特性java.time包下的具体类型参数来直接接收. 我们使用含有java.time封装类型的 ...

  5. 解决阿里云专有网络ftp无法远程链接

    配置好ftp后本机测试可用但无法远程连接 网络上找了很多方法,配置防火墙出入站规则均无效 提交阿里云工单,给出解决方法,测试后可用

  6. 经典面试题:分布式缓存热点KEY问题如何解决--有赞方案

    有赞透明多级缓存解决方案(TMC) 一.引子 1-1. TMC 是什么 TMC ,即"透明多级缓存( Transparent Multilevel Cache )",是有赞 Paa ...

  7. ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存

    ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存 part 1:给我点时间,允许我感慨一下2016年 正好有时间,总结一下最近使用的一些技术,也算是为2016年画上一个完 ...

  8. 基于redis分布式缓存实现

    Redis的复制功能是完全建立在之前我们讨论过的基 于内存快照的持久化策略基础上的,也就是说无论你的持久化策略选择的是什么,只要用到了Redis的复制功能,就一定会有内存快照发生,那么首先要注意你 的 ...

  9. EhCache 分布式缓存/缓存集群

    开发环境: System:Windows JavaEE Server:tomcat5.0.2.8.tomcat6 JavaSDK: jdk6+ IDE:eclipse.MyEclipse 6.6 开发 ...

  10. .net 分布式架构之分布式缓存中间件

    开源git地址: http://git.oschina.net/chejiangyi/XXF.BaseService.DistributedCache 分布式缓存中间件  方便实现缓存的分布式,集群, ...

随机推荐

  1. 牛客网-SQL专项训练20

    ①学生.书店和图书三个实体集之间的联系属于:多元联系. 解析: 参与联系的实体集个数大于2个时,为多元联系:这里学生.书店.图书是三个实体,为多元联系. 二元联系指只有两个实体集参与的联系: 自反联系 ...

  2. 基于 OPLG 从 0 到 1 构建统一可观测平台实践

    简介: 随着软件复杂度的不断提升,单体应用架构逐步向分布式和微服务的架构演进,整体的调用环境也越来越复杂,仅靠日志和指标渐渐难以快速定位复杂环境下的问题.对于全栈可观测的诉求也变得愈加强烈,Trace ...

  3. 持续定义Saas模式云数据仓库+实时搜索

    简介: 本文由阿里云计算平台事业部 MaxCompute 产品经理孟硕为大家带来<持续定义Saas模式云数据仓库+实时搜索>的相关分享.以下是视频内容精华整理,主要包括以下三个部分:1.W ...

  4. 数据湖揭秘—Delta Lake

    ​简介:Delta Lake 是 DataBricks 公司开源的.用于构建湖仓架构的存储框架.能够支持 Spark,Flink,Hive,PrestoDB,Trino 等查询/计算引擎.作为一个开放 ...

  5. 从KPI到OKR,高阶产品人如何推动业务高速增长

    简介: 不管是核心大目标,还是O(Objectives),或者北极星指标,奇妙等式等等,最后都需要核心组织协同方式来推动整个目标聚焦以及过程的落地. 作为产品经理人,相信很多人都遇到过以下的灵魂拷问: ...

  6. [Kali] Kali 信息收集

      网络空间测绘. 网络空间测绘是2016年出现的一个概念,主要指用一些技术方法,来探测全球互联网空间上的节点分布情况和网络关系索引,构建全球互联网图谱的一种方法. nmap端口扫描. 子域名爆破. ...

  7. [ML] 详解 ChatGLM-webui 的启动使用与 ChatGLM-6B 常见问题

      1. ChatGLM-webui 总共支持以下几个命令选项: 2. 以 windows 为例,在 PowerShell 里运行命令: # 安装依赖 pip install torch==1.13. ...

  8. [Gin] gin-jwt 中间件的请求流程与使用思路

    gin-jwt 中间件是对 jwt-go 的封装以适应 gin 框架.gin-jwt 对不同的请求流程有不同的 handler: 登录请求流程 是用 LoginHandler. 需要 jwt 令牌的后 ...

  9. 3种方式自动化控制APP

    自动化控制APP不管是在工作还是生活方面,都可以帮助我们高效地完成任务,节省时间和精力.本文主要介绍自动化控制APP的3种常用方式. 1.Python + adb 这种方式需要对Android有一些基 ...

  10. 7.deployment扩容-查看pod使用的CPU-统计ready状态节点数量

    官方文档:https://kubernetes.io/zh-cn/docs/tasks/run-application/scale-stateful-set/题目1: 将名为loadbalancer的 ...