下面是一个标准的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. 力扣1082(MySQL)-销售分析Ⅰ(简单)

    题目: 产品表:Product 销售表:Sales 编写一个 SQL 查询,查询总销售额最高的销售者,如果有并列的,就都展示出来. 以 任意顺序 返回结果表. 查询结果格式如下所示. Product ...

  2. [ABC342D] Square Pair 题解

    [题目描述] 给定一个长度为 \(N\) 的非负整数序列 \(A=\left(A_1,\cdots,A_n\right)\).求满足以下条件的整数对 \(\left(i,j\right)\) 的数量. ...

  3. 全链路灰度之 RocketMQ 灰度

    ​简介:本文将以上次介绍过的<如何用 20 分钟就能获得同款企业级全链路灰度能力?>中的场景为基础,来进一步介绍消息场景的全链路灰度. 作者:亦盏 之前的系列文章中,我们已经通过全链路金丝 ...

  4. 龙蜥利器:系统运维工具 SysAK的云上应用性能诊断 | 龙蜥技术

    ​简介:本文从大量的性能诊断实践出发,来介绍 SysAK 在性能诊断上的方法论及相关工具. ​ 文/张毅:系统运维SIG核心成员.SysAK 项目负责人:毛文安:系统运维 SIG 负责人. 系统运维既 ...

  5. 自动化测试数据生成:Asp.Net Core单元测试利器AutoFixture详解

    引言 在我们之前的文章中介绍过使用Bogus生成模拟测试数据,今天来讲解一下功能更加强大自动生成测试数据的工具的库"AutoFixture". 什么是AutoFixture? Au ...

  6. docker-compose 安装redis

    一. docker 拉去最新版本的redis `docker pull redis:6.0.6` #后面可以带上tag号, 默认拉取最新版本 二. docker安装redis 执行命令: mkdir ...

  7. 关于SQL数据库Varchar字符串类型长度设计问题(转载)

    为什么要合理的设计数据库字段数据类型的长度?个人观点:一个是降低物理上的存储空间,一个是提高数据库的处理速度,还有一个附带功能是能校验数据是否合法.   现代数据库一般都支持CHAR与VARCHAR字 ...

  8. Android开发环境配置 JDK及SDK

    已经搭建过无数次开发环境,今天把搭建环境记录下,下次不用去搜索别人博客,有些博客都是复制粘贴,有些关键信息都缺失了. 1.首先第一步:下载JDK,配置JDK环境变量.JDK可以在Oracle官网下载, ...

  9. tarjan板子整理

    缩点 stack<int>q; void tarjan(int u) { pre[u]=low[u]=++cnt; q.push(u); vis[u]=1; for(int i=head[ ...

  10. JDBC连接MySQL 8时报错:MySQLNonTransientConnectionException: Public Key Retrieval is not allowed

    需要设置属性 IDEA DBerver