因MemoryCache闹了个笑话

前言

是这么一回事:

我正在苦思一个业务逻辑,捋着我还剩不多的秀发,一时陷入冥想中……

突然聊天图标一顿猛闪,打开一看,有同事语音;

大概意思是:同事把项目中Redis部分缓存换成MemoryCache/Memcached,还强调MemoryCache/Memcached的效率是Redis的2~5倍;

当时我想到的是Memcached,听到的似乎也是,心想:怎么可能,就算有性能差,也不至于那么多;

因为当时同事代码还没提交,然后就陷入讨论ing,最后还是没聊通,我就跑到同事那当面沟通(要去打架吗,不不不,文明人);

沟通中…..,好几分钟过去了,突然同事说:他用的是微软的MemoryCache

虽然从读音上我还没区分出来,但一听微软,我就感觉我成笑话啦;

然后赶紧让同事打开代码,我擦,真成笑话啦,还理直气壮的沟通了好几十分钟。

为什么会那么“理直气壮”?

  • Memcached(听错的)性能高于Redis的2~5倍产生重大怀疑,经验告诉我不可能,除非Redis用法有问题;

  • 同事把Redis换成Memcached(听错的),那肯定不行的,前期的技术选型,Memcached不太符合项目应用场景;

最后因为MemoryCache成就了一场笑话,那MemoryCacheMemcached有什么区别呢?

  • MemoryCache不是分布式缓存,是基于程序存储在内存中的;是微软封装好的内存缓存库,合理利用CPU,性能好;由于基于程序分配内存,使用时避免了网络通讯的消耗。

  • Memcached是分布式缓存,是存储在公共机器上的,供不同程序使用的,存在一定的网络传输消耗。

这样比较感觉有点勉强,虽然Memcached是分布式的,但也是基于内存的,在数据存储内存的逻辑还是不同的,不过这里不打算讲解源码,我要说应用,哈哈哈。

附加-为什么Redis让同事感觉性能不好

真实场景是这样的,客户端开启多线程频繁读取Redis数据,当访问比较多时,导致Redis读取数据超过20毫秒,对于Web项目来说其实这还好,20毫秒的响应用户根本无法感知。但对于一个高性能要求的服务程序来说,对通讯要求就比较高,所以简单分析了一下拖慢的原因,大概以下两点:

  • 客户端增多,导致一个常用Key对应的数据变大(其实不大,只是相对大,稍微影响了读取速度,毫秒级别);

    解决方案:同事使用MemoryCache多做一层缓存,将这个常用Key直接存在内存中,提高读取性能;

  • 使用类似于Keys * 的命令频繁获取数据,导致有些命令执行在20毫秒左右(慢日志中可以看到);

    解决方案:改用Scan类似命令获取数据;

  • Redis自身的持久化耗时;

    解决方案:适当调整Redis持久化策略,让持久化频率没那么高;

正文

回归正题,既然说到MemoryCache,就来简单聊聊,主要分享在项目实战中如何使用;

主要依赖包:Microsoft.Extensions.Caching.Memory

MemoryCache的使用很简单,就是在调用方法设置和获取值就对啦;来直接看Demo吧;

1. 控制台Demo

其实有很多程序是基于后台服务运行的,并不都是Web,所以写了一个控制台的Demo,方便小伙伴参考;

1.1 引入相关包,项目中使用了Autofac作为依赖注入和其切面编程,则需要引入相关的依赖包,项目结构和包引入如下图:

1.2 编写示例代码及注册相关服务
  • IUserService就是简单接口;


    接口和方法上标注的Intercept和MyCache特性不是必须的,接下来会说;

  • UserService对接口的实现;

  • MyCacheAttribute自定义特性,用于标识,里面没有任何逻辑处理;



  • MyInterceptor自定义拦截器,面向切面的逻辑代码在这里处理;



    代码完了,就开始使用Autofac注册服务,进行使用啦,如下:



注:Autofac不是必须的,根据自己需要进行选择使用,这里是为了要使用Autofac的切面编程功能。

1.3 两种方式进行缓存处理

通常在非Web程序中,有以下两种方式进行缓存处理:

代码嵌入到业务逻辑,在真实业务逻辑处进行缓存获取或设置;


这样很大一个缺点是每一个缓存的数据都需要手动到指定业务逻辑中添加缓存处理,代码后期不好维护,缓存功能的开启和关闭也不好控制,需要修改代码进行满足。

面向切面编程,无需嵌入多余代码到业务中

通过面向切面的思想,以动态代理的原理拦截方法,在方法前后进行处理,如下:


缓存逻辑直接放在拦截器中处理即可,如下:


注册服务时,开启Autofac的面向切面功能即可


运行看效果,第二次都是从缓存中获取数据,美美哒:

注:推荐使用面向切面的形式进行处理,这样缓存功能可插拔,代码维护性也好。

2.WebApiDemo(项目名称为:MemoryCacheWebApiDemo)

在WebApi中使用就比较简单啦,关于MemoryCache的依赖包已经集成在框架中,如果需要使用,直接注册服务就可以用啦;通常在WebApi中进行缓存处理的方式有三种:

  • 中间件形式:通过自定义中间件进行缓存逻辑操作;

  • 过滤器形式:使用MVC相关过滤器进行缓存逻辑操作;

  • 业务层面向切面形式:面向切面的方式,在业务层做缓存,集成Autofac即可,和控制台Demo的面向切面一样;

这里就用过滤器的形式进行Demo演示,走起来~~~

2.1 编写过滤器

缓存如果能在最前面处理,就优先在最前面,所以使用的ResourceFilter过滤器;关于过滤器之前写过一篇文章很详细(跟我一起学.NetCore之MVC过滤器,这篇看完走路可以仰着头走),这里就不赘述了。

然后在Startup.cs中注册服务和将自定义过滤器注册即可,如下:

然后启动运行,多次请求调试看看效果(小伙伴自己在过滤器中调试即可);

在WebApi中也可以使用业务层面向切面的方式进行相关业务处理,集成Autofac即可;小伙伴可以参照这篇文章(跟我一起学.NetCore之Asp.NetCore中集成Autofac扩展)。关于AOP面向切面编程这块,后续单独整理一篇分享;

源码地址:https://github.com/zyq025/DotNetCoreStudyDemo

总结

在一些开发项目中,可能会使用Dictionary进行数据缓存,如果是这样,可以尝试使用MemoryCache,性能合理利用CPU,而且还是线程安全的;另外在高并发场景,可以用其作为多级缓存,因为MemoryCache还能设置过期时间,搭配Redis配合使用,效果杠杠的。

一个被程序搞丑的帅小伙,关注"Code综艺圈",跟我一起学~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/304308.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单片机c语言位运算写法,单片机与嵌入式系统中C语言的位运算小记

原标题&#xff1a;单片机与嵌入式系统中C语言的位运算小记编了个PIC的项目&#xff0c;对里的还是蛮有感悟的&#xff0c;特此记录一下。譬如说&#xff0c;在程序中定义了一个char类型的变量&#xff0c;purge_short_enable_flag&#xff0c;//bit<0>-- start short ci…

wenstorm设置谷歌_WebStorm+Chrome调试Vue步骤

在调试时请 注意:在WebStorm中启动调试时&#xff0c;WebStorm会根据你设置的url&#xff0c;自动打开新的Chrome浏览器进程访问这个设置的url&#xff0c;而且这个浏览器页面和你平常看到的浏览器差异会比较大&#xff0c;看不到书签栏&#xff0c;也看不到你先前所装的所有插…

Coursera吴恩达《卷积神经网络》课程笔记(1)-- 卷积神经网络基础

推荐阅读时间&#xff1a;8min~15min主要内容&#xff1a;卷积神经网络《Convolutional Neural Networks》是Andrw Ng深度学习专项课程中的第四门课。这门课主要介绍卷积神经网络&#xff08;CNN&#xff09;的基本概念、模型和具体应用。该门课共有4周课时&#xff0c;所以我将…

反转一个整数

原型&#xff1a;unsigned Reverse(unsigned int n) ; 我的代码&#xff1a;用了浮点函数log10, pow不仅效率低&#xff0c;还会损失精度。 1 unsigned Reverse(unsigned n)2 {3 intdigits (int)log10((double)n) ;4 5 intr 0;6 while(n)7 {8 intt n %10;9 r t *pow((double)10…

如何友好的处理 WebApi 中抛出的错误

微软的 ASP.NET Web API 是一个轻量级的web框架&#xff0c;可用来构建基于 http 无状态的rest服务&#xff0c;异常是一种运行时错误&#xff0c;异常处理是一种处理运行时错误的技术&#xff0c;每一个开发者都应该知道如何处理 Web API 中的异常&#xff0c;并且在 Action 中…

纯c语言实现的改进暗通道去雾算法测试程序(附赠大量测试图像),基于改进暗通道先验算法的图像去雾...

邱清辉摘要&#xff1a;针对普通暗通道先验算法去雾能力的不足&#xff0c;本文提出了一种改进算法&#xff0c;通过采用高斯平滑将原图像分为基础子图和细节子图&#xff0c;基础子图采用暗通道先验算法&#xff0c;细节子图采用gamma变换方法&#xff0c;再采用图像融合进行融…

第jiu届蓝桥杯单片机省赛真题_第九届蓝桥杯单片机组省赛试题.pdf

第九届蓝桥杯单片机组省赛试题“彩灯控制器”的程序设计与调试 (70 分)一、基本要求1.1 使用CT107D 单片机竞赛板&#xff0c;完成“彩灯控制器”功能的程序设计与调试&#xff1b;1.2 设计与调试过程中&#xff0c;可参考组委会提供的“资源数据包”&#xff1b;1.3 Keil 工程…

为什么离开学校后,学习能力直线下降?

最近几年&#xff0c;人工智能浪潮层层推进&#xff0c;对各大科技公司产生巨大影响。百度推出Apollo无人车计划&#xff0c;阿里建立达摩院&#xff0c;腾讯成立的AI Lab虽布局较晚却也不甘人后。ChinaAI已是大势所趋&#xff0c;吸引的不仅是大公司&#xff0c;更有许多人工智…

android6.0重力工具箱,重力工具箱 GravityBox For Android8.0/8.1(Oreo)稳定版发布!

作为功能最强大的Xposed框架模块之一&#xff0c;重力工具箱 GravityBox的更新适配一直也是最积极的&#xff0c;本次发布的8.x专用版本也算是比较及时&#xff0c;每一个大的Android版本&#xff0c;重力工具箱基本都会有一个专门的版本来适配&#xff0c;当然基础功能也会略有…

如何在 ASP.Net Core 中使用 MediatR

MediatR 是一个 中介者模式 的.NET开源实现&#xff0c; 中介者模式 管控了一组对象之间的相互通讯并有效的减少了对象之间错综复杂的相互依赖&#xff0c;在 中介者模式 中&#xff0c;一个对象不需要直接和另一个对象进行通讯&#xff0c;而是通过 中介者 进行转达&#xff0…

pythonjson数据提取_python爬虫学习笔记(十)-数据提取之JsonPath的使用

1. JSON与JsonPATHJSON(JavaScript Object Notation) 是一种轻量级的数据交换格式&#xff0c;它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。适用于进行数据交互的场景&#xff0c;比如网站前台与后台之间的数据交互。JSON和XML的比较可谓不相上下。Pyt…

全球100款大数据工具汇总(前50款)

01 Talend Open Studio是第一家针对的数据集成工具市场的ETL(数据的提取Extract、传输Transform、载入Load)开源软件供应商。Talend的下载量已超过200万人次&#xff0c;其开源软件提供了数据整合功能。其用户包括美国国际集团&#xff08;AIG&#xff09;、康卡斯特、电子港湾…

NLP快速入门:手把手教你用HanLP做中文分词

导读&#xff1a;随着自然语言处理(Natural Language Processing, NLP)技术日趋成熟&#xff0c;实现中文分词的工具也越来越多。中文分词技术作为中文自然语言处理的第一项核心技术&#xff0c;是众多上层任务的首要基础工作&#xff0c;同时在日常的工作中起着基础性的作用。…

微信小程序android错误,app安卓端 跳转到微信小程序失败

详细问题描述(DCloud产品不会有明显的bug&#xff0c;所以你遇到的问题大都是在特定环境下才能重现的问题&#xff0c;请仔细描述你的环境和重现方式&#xff0c;否则DCloud很难排查解决你的问题)[内容] app安卓端跳转到微信小程序失败重现步骤 一直失败[步骤] 微信小程序关联了…

动态内存(Dynamic Memory),微软的内存过量分配技术?

Hyper-V不支持Memory Overcommitment&#xff0c;一直为VMware和其他虚拟化厂商所诟病。当然&#xff0c;微软一直不承认这是他们的软肋&#xff0c;认为为了保证生产环境VM的性能&#xff0c;过量分配内存是不合时宜的。但是&#xff0c;微软的态度似乎突然转变&#xff0c;3月…

openlayers地图旋转_OpenLayers的使用---- 一个完全免费开源的地图JS库

OpenLayers很容易的在网站里放置动态地图。它能显示展开图及从资源中加载地图标记及矢量数据。它被开发出尽可能的使用所有的地图信息。并且它是完全免费及开源的.详细了解可去它的官网&#xff1a;http://openlayers.org/简单使用&#xff0c;如展示一个块地图.mymap {height:…

程序员上帝视角解读“旅行青蛙”,你的呱真的在旅行嘛?

来源&#xff1a;知乎作者&#xff1a;黄小秋原文链接&#xff1a;https://www.zhihu.com/question/68733553/answer/305463907导语&#xff1a;知乎有位程序员大佬&#xff0c;为了让老母亲老父亲们理解自己的呱究竟在干什么&#xff0c;于是花了五个晚上逆向游戏程序逻辑&…

android.mk 翻译,翻译ANDROID-MK.TXT

Android.mk编译文件是用来向Android NDK描述你的C,C源代码文件的&#xff0c;这篇文档描述了它的语法。在阅读下面的内容之前&#xff0c;假定你已经阅读了docs/OVERVIEW.TXT文件&#xff0c;了解了它们的脚色和用途。概述:一个Android.mk file用来向编译系统描述你的源代码。具…

我为什么对TypeScript由黑转粉?

喜欢就关注我们吧&#xff01;一名曾仅使用 JavaScript 的开发者解释自己为何从反对 TypeScript 到转变为 TypeScript 粉丝。Chirag Swadia 自称曾是 Anti-TypeScript 的 JavaScript 开发者。谈及反对的原因&#xff0c;他以前一直认为给函数/变量添加类型以满足 TypeScript 编…

谈谈关于MVP模式中V-P交互问题

在差不多两年的时间内&#xff0c;我们项目组几十来号人都扑在一个项目上面。这是一个基于微软SCSF&#xff08;Smart Client Software Factory&#xff09;的项目&#xff0c;客户端是墨尔本一家事业单位。前两周&#xff0c;我奉命负责对某个模块进行Code Review工作&#xf…