程序员修神之路--高并发下为什么更喜欢进程内缓存

640?wx_fmt=gif

菜菜哥,告诉你一个好消息

640?wx_fmt=png640?wx_fmt=jpeg

YY妹子,什么好消息,你有男票了?

640?wx_fmt=png640?wx_fmt=jpeg

不是啦,我做的一个网站,以前经常由于访问量太大而崩溃,现在我加上了缓存,很稳定啦

640?wx_fmt=png640?wx_fmt=jpeg

加的什么缓存呢?

640?wx_fmt=png640?wx_fmt=jpeg

我用的redis,号称业界最快的缓存组件了

640?wx_fmt=png640?wx_fmt=jpeg

你觉得现在的缓存操作应该是最快的了吗?

640?wx_fmt=png640?wx_fmt=jpeg

是的,我觉得没有缓存能比这种模式更快了

640?wx_fmt=png640?wx_fmt=jpeg

你先停停,我给你先讲个故事

640?wx_fmt=png640?wx_fmt=jpeg640?wx_fmt=png

进程内缓存是指缓存和应用程序在相同地址空间。即同一个进程内。分布式缓存是指缓存和应用程序位于不同进程的缓存,通常部署在不同服务器上。


        从前有个机构,机构的主人叫做 CPU,这个机构专门派仆人取一些东西然后做相应的处理。下面是这个机构日常的场景。


640?wx_fmt=jpeg

cpu

赶紧去我的仓库L1缓存取点东西

640?wx_fmt=gif

仆人

主人你要的东西,那里离我们最近,所以很快,但是空间比较小。

640?wx_fmt=jpeg640?wx_fmt=jpeg

cpu

你丫还挺快,只用了大约一秒

640?wx_fmt=jpeg


640?wx_fmt=jpeg

cpu

赶紧去仓库 L2缓存取点东西

640?wx_fmt=gif

仆人

主人你要的东西,那里离我们也很近,比L1缓存远一点,但是也很快,空间比较小,但是比L1缓存的空间大。

640?wx_fmt=jpeg640?wx_fmt=jpeg

cpu

速度还可以,大约20秒就回来了

640?wx_fmt=jpeg

640?wx_fmt=jpeg

cpu

街上有一个地方叫内存,赶紧去取点东西

640?wx_fmt=gif

仆人

主人你要的东西,内存这个地方空间很大呀,就是稍微远了点

640?wx_fmt=jpeg640?wx_fmt=jpeg

cpu

居然用了5分钟,等你这段时间我都刷了好几个段子了

640?wx_fmt=jpeg

640?wx_fmt=jpeg

cpu

有一个叫做磁盘的小镇,赶紧去取点东西

640?wx_fmt=gif

仆人

主人你要的东西,磁盘这个地方空间太大呀,取点东西很慢呀

640?wx_fmt=jpeg640?wx_fmt=jpeg

cpu

居然用了5天,等你这段时间我都能抱团来一个周边游了

640?wx_fmt=jpeg

640?wx_fmt=jpeg

cpu

有一个叫做互联网的国度,赶紧去取点东西

640?wx_fmt=gif

仆人

主人你要的东西,互联网太远了,取点东西太费劲了

640?wx_fmt=jpeg640?wx_fmt=jpeg

cpu

居然用了15天,等你去互联网取东西,简直就是在浪费我的生命

640?wx_fmt=jpeg

cpu

当我做完一个委托人的任务,切换到另外一个委托人的任务时候,我需要把上一个委托人的一些信息先记录下来,然后还需要把新委托人的信息读取一遍,这个过程我是很耗时的,大约需要一个小时呢

以上故事纯属预估数据,真实数据会根据不同的硬件配置和网络环境有误差。


        通过以上不正经的小故事,我们可以了解到cpu取各个设备数据的大体差距。至于YY妹子的问题,大家也应该了解了。


1.  首先把数据从磁盘加载到内存做缓存,这个是对的。毕竟磁盘的IO速度比内存要慢的多。就拿我们现在使用的大多数PC机以及服务器来说,磁盘往往是性能的瓶颈。

2.  如果有条件或者框架支持可以实现进程内缓存,我还是推荐使用进程内缓存,毕竟类似Redis这样的kv存储和应用程序多数情况不在一台服务器上,虽然局域网的速度肉眼看起来非常快,但是对于cpu来讲,还是让cpu休了一个大假。


    至于什么情况下适合应用进程内缓存,我觉得有几点需要注意:

1.  相同的请求或者设置的相同缓存key的请求每次都是同一个服务器上的同一个程序去处理,这样这个请求的缓存正常情况下只会产生一份。 如果每次请求都会路由到不同的服务器,便会产生多个缓存的副本,维护这些缓存数据的一致性是需要代价的。

2.  当有新的服务器节点加入或者服务器节点退出的时候,不能发生雪崩现象,所有缓存请求都穿透到达数据库,那是比较要命的。比如可以看一下菜菜以前的文章:分布式缓存的一条明路(附代码)

3.  如果缓存的处理服务器发生变化,比如:由于某种原因,开始请求是由服务器A来处理,后来A服务器down了,现在由服务器B来处理,在缓存转移的过程中,必须能保证数据的正确性和一致性。

4.  程序的进程内缓存必须有过期策略,在有限内存大小的情况下,合理的使用。推荐使用LRU淘汰算法来保证内存不会撑爆。

5.  系统的并发量及其大,对性能的要求及其高,可以考虑使用进程内缓存。

6.  如果是小部分只读数据,并且访问量比较大,例如经常使用的字典数据等,可以考虑使用进程内缓存。


    相对于分布式缓存,比如Redis,进程内缓存有哪些优势呢?

1.  进程内缓存性能比较高,延迟会更小,更节省带宽,毕竟分布式缓存网络调用的性能和本地调用比起来慢太多,

2.  由于和应用程序位于同一进程,共享相同的虚拟内存,所以在状态维护上更容易一些,

3.  其次进程内的缓存不设计到网络传输,所以没有序列化的过程,在性能上更胜一筹。

4.  进程内缓存的数据类型几乎可以是语言级别支持的任意类型,数据类型设计上比大多数分布式缓存设备支持要灵活许多。


        在应对高并发的情况下,如果有适当的环境菜菜还是觉得进程内缓存为首选,另外一点程序要尽量避免线程切换,尽量异步化。如果可以最好能预估出缓存数据的大小,避免内存泄漏等现象发生。

        当然分布式缓存有自己的优势,在监控,容灾,扩展性,易用性等方面更胜一筹。至于用进程内还是分布式缓存,没有定论,能解决业务痛点就是最好的结果


写在最后

程序如果要想最大程度的提升并发量,缩短响应时间, 就把用户需要的数据放在离用户最近的地方


640?wx_fmt=jpeg


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

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

相关文章

CF364B. Free Market

CF364B. Free Market Solution 显然最终能取到的物品必然是按cic_ici​从小到大排序后的一段前缀。能取到的价值集合可由这段前缀做背包得到。每一轮取数的价值最多增加ddd。 因此先对所有cic_ici​做背包,从000开始每次贪心地选取距离不超过ddd的能被ccc表出的最…

6月数据库排行:PostgreSQL和MongoDB分数罕见下降

DB-Engines 数据库流行度排行榜 6 月更新已发布,排名前二十如下:总体排名和上个月相比基本一致,其中排名前三的 Oracle、MySQL 和 Microsoft SQL Server 也是分数增加最多的三个数据库,增加的分数分别为 13.67、4.67 和 15.57&…

CF611F. New Year and Cleaning

CF611F. New Year and Cleaning Solution 还挺巧妙的套路。 把起点整体看作一个矩阵,在操作时移出原来矩阵外的部分的起点都是超越边界的,可以直接通过超出的面积计算贡献,再把超出的部分删去,模拟即可(第一轮模拟会…

在ASP.Net Core 中使用枚举类而不是枚举

前言:我相信大家在编写代码时经常会遇到各种状态值,而且为了避免硬编码和代码中出现魔法数,通常我们都会定义一个枚举,来表示各种状态值,直到我看到Java中这样使用枚举,我再想C# 中可不可以这样写&#xff…

CF626E. Simple Skewness

CF626E. Simple Skewness Solution 先排序。 nnn为奇数时,枚举中位数,两边贪心地选择最大的数,显然平均数是凸函数,三分即可确定最值。 当nnn为偶数时,必然选择最大值,然后转化为nnn为奇数的情况。 PS&a…

ASP.NET Core 中的错误处理

1.前言ASP.NET Core处理错误环境区分为两种:开发环境和非开发环境。●开发环境:开发人员异常页。●非开发环境:异常处理程序页、状态代码页。在Startup.Configure方法里面我们会看到如下代码:env.IsDevelopment()是判断应用程序运…

Java研学-Servlet 进阶

一 请求对象 1 HttpServletRequest HttpServletRequest 是一个接口,该接口的实现类对象称为请求对象,请求对象封装了所有的请求信息(请求行,请求头,请求体(请求参数))。   HttpServletRequest 接口包含了大量的方法。由 Tomcat…

CF626F. Bear and Fair Set

CF626F. Bear and Fair Set Solution 单走一个网络流。 先对余数0..40..40..4分别建一个点,从S−>0..4S->0..4S−>0..4分别连容量n/5n/5n/5的边。 对于每一个限制,相当于把[0,b][0,b][0,b]分成了若干个小区间,并且可以求得每个小…

ASP.NET Core SameSite 设置引起 Cookie 在 QQ 浏览器中不起作用

最近在发布了基于 ASP.NET Core 实现的新版登录页面之后,陆陆续续地接到用户反馈登录时 Antiforgery Token 总是验证失败。日志中记录的对应错误是今天在 QQ 浏览器中将内核模式设置为“总是使用 IE 内核”重现了问题,通过浏览器的开发者工具查看 cookie…

CF372D. Choosing Subtree is Fun

CF372D. Choosing Subtree is Fun Solution 想了一晚都不会,一觉醒来就悟了QwQQwQQwQ 之前一直想着如何用类似树形DPDPDP的方法求出每一个点的贡献再合并,然后突然发现直接枚举区间就行了。 考虑区间确定时,其实就是求区间内节点在原树上的…

ASP.NET Core - 基于IHttpContextAccessor实现系统级别身份标识

问题引入:我们知道当请求通过认证模块时,会给当前的HttpContext赋予当前用户身份标识,我们在需要授权的控制器中打上[Authorize]授权标签,就可以在ControllerBase的User属性获取到基于声明的权限标识(ClaimsPrincipal)。遗憾的是这…

怎样学习和阅读技术书籍?

技术的更新换代非常的迅速,作为一个技术人,需要持续不断地学习才能不被淘汰。但是学习没有速成的方法,只可能有一些技巧让我们事半功倍,本文是我对学习和读书的一点思考。学习是一件「逆人性」的事,如果让你选择是学习…

CF653F. Paper task

CF653F. Paper task 简要题面 给定括号序列SSS,求其中本质不同合法括号序列个数。(∣S∣≤5∗105|S|\leq 5*10^5∣S∣≤5∗105) Solution 感觉用了一个很麻烦的方法。 我们可以考虑枚举本质不同串的右端点,每次动态地在SAMSAMSAM里面加入末尾元素&am…

52ABP和ABP的关系

52ABP和ABP的关系本文作者:52ABP开发团队 文章会随着版本进行更新,关注我们获取最新版本 本文出处:https://www.52abp.com/wiki/common/latest 源代码: https://www.github.com/52abp 52ABP和ABP的关系ASP.NET Boilerplate是一个开…

CF1167F. Scalar Queries

CF1167F. Scalar Queries Solution 拆贡献,自身的贡献为bi∗(i−1)∗(n−i)b_i*(i-1)*(n-i)bi​∗(i−1)∗(n−i),每一个左边比他小的数bjb_jbj​会产生bi∗j∗(n−i)b_i*j*(n-i)bi​∗j∗(n−i)的贡献,需要维护∑j\sum_{j}∑j​&#xff0…

【译】C#9的候选功能

通往C# 9 的漫长道路已经开始了,这是世界上第一篇关于C# 9候选功能的文章。阅读完本文后,你将希望为将来遇到新的C#挑战做好充分准备。 这篇文章基于:C#语言版本计划 9.0 候选功能基于记录和模式匹配的表达式我一直在长时间等待这个功能。记录…

CF641D. Little Artem and Random Variable

CF641D. Little Artem and Random Variable Solution 设给定的两个序列为mx1..n,mn1..nmx_{1..n},mn_{1..n}mx1..n​,mn1..n​。 令第一个骰子投到1..n1..n1..n的概率为p1..np_{1..n}p1..n​ 令第二个骰子投到1..n1..n1..n的概率为q1..nq_{1..n}q1..n​ 显然有 mxi(∑j≤ipj)…

AKS开讲啦! | DevOps with AKS

上周小Phippy搬到了Kube船长船上的Pods里,感觉好极了,那今天我们继续看看Phippy的兴趣爱好哦。探索Kube船上的世界上篇(点击回顾)小Phippy 搬到了船上的Pods里,感受到了回家般的舒适感,小Phippy希望能发挥一…

CF1157G. Inverse of Rows and Columns

CF1157G. Inverse of Rows and Columns Solution 首先枚举第一行是否变换&#xff0c;再枚举第一行的010101状态&#xff0c;即可确定列变换。 然后对于之后的行变换&#xff0c;从前往后贪心地让111出现得尽可能晚即可。 Code #include <vector> #include <list&…

把文件隐藏在图片中

一、前言有的时候我们需要把文件给隐藏起来&#xff0c;但是Windows自带的隐藏方式还是很容易被发现的。这时候我们可以选择把文件放在网盘&#xff0c;但这毕竟需要网络。不过&#xff0c;我们可以通过Windows自带的功能&#xff0c;把文件隐藏在图片中。是不是有一种大隐隐于…