进程内缓存,究竟怎么玩?

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/z50L2O08e2u4afToR9A/article/details/80809269

除了常见的redis/memcache等进程外缓存服务,缓存还有一种常见的玩法,进程内缓存

 

什么是进程内缓存?

:将一些数据缓存在站点,或者服务的进程内,这就是进程内缓存。

 

进程内缓存的实现载体,最简单的,可以是一个带锁的Map。又或者,可以使用第三方库,例如leveldb。

 

进程内缓存能存储啥?

:redis/memcache等进程外缓存服务能存什么,进程内缓存就能存什么。

640?wx_fmt=png

如上图,可以存储json数据,可以存储html页面,可以存储对象

 

进程内缓存有什么好处?

与没有缓存相比,进程内缓存的好处是,数据读取不再需要访问后端,例如数据库。

640?wx_fmt=png

如上图,整个访问流程要经过1,2,3,4四个步骤。

 

如果引入进程内缓存,

640?wx_fmt=png

如上图,整个访问流程只要经过1,2两个步骤。

 

与进程外缓存相比(例如redis/memcache),进程内缓存省去了网络开销,所以一来节省了内网带宽,二来响应时延会更低

 

进程内缓存有什么缺点?

:统一缓存服务虽然多一次网络交互,但仍是统一存储。

640?wx_fmt=png

如上图,站点和服务中的多个节点访问统一的缓存服务,数据统一存储,容易保证数据的一致性。

 

640?wx_fmt=png

而进程内缓存,如上图,如果数据缓存在站点和服务的多个节点内,数据存了多份,一致性比较难保障

 

如何保证进程内缓存的数据一致性?

:保障进程内缓存一致性,有几种方案。

 

640?wx_fmt=png

第一种方案,可以通过单节点通知其他节点。如上图:写请求发生在server1,在修改完自己内存数据与数据库中的数据之后,可以主动通知其他server节点,也修改内存的数据。

 

这种方案的缺点是:同一功能的一个集群的多个节点,相互耦合在一起,特别是节点较多时,网状连接关系极其复杂。

 

640?wx_fmt=png

第二种方案,可以通过MQ通知其他节点。如上图,写请求发生在server1,在修改完自己内存数据与数据库中的数据之后,给MQ发布数据变化通知,其他server节点订阅MQ消息,也修改内存数据。

 

这种方案虽然解除了节点之间的耦合,但引入了MQ,使得系统更加复杂

 

前两种方案,节点数量越多,数据冗余份数越多,数据同时更新的原子性越难保证,一致性也就越难保证

 

640?wx_fmt=png

第三种方案,为了避免耦合,降低复杂性,干脆放弃了“实时一致性”,每个节点启动一个timer,定时从后端拉取最新的数据,更新内存缓存。在有节点更新后端数据,而其他节点通过timer更新数据之间,会读到脏数据。

 

为什么不能频繁使用进程内缓存?

分层架构设计,有一条准则站点层、服务层要做到无数据无状态,这样才能任意的加节点水平扩展,数据和状态尽量存储到后端的数据存储服务,例如数据库服务或者缓存服务。

 

可以看到,站点与服务的进程内缓存,实际上违背了分层架构设计的无状态准则,故一般不推荐使用。

 

什么时候可以使用进程内缓存?

:以下情况,可以考虑使用进程内缓存。

情况一只读数据,可以考虑在进程启动时加载到内存。

画外音:此时也可以把数据加载到redis / memcache,进程外缓存服务也能解决这类问题。

 

情况二极其高并发的,如果透传后端压力极大的场景,可以考虑使用进程内缓存。

例如,秒杀业务,并发量极高,需要站点层挡住流量,可以使用内存缓存。

 

情况三,一定程度上允许数据不一致业务

例如,有一些计数场景,运营场景,页面对数据一致性要求较低,可以考虑使用进程内页面缓存


末了,再次强调,进程内缓存的适用场景并不如redis/memcache广泛,不要为了炫技而使用


更多的时候,还是老老实实使用redis/mc吧。

画外音:额,介绍技术,不希望把大家带偏了。

 

相关推荐:

挖坑篇:《缓存架构,到底设计些什么?

填坑篇一:《从源码分析,究竟选型redis还是memcache

填坑篇二:《“选redis还是memcache”,面试官究竟想考察啥?


任何脱离业务的架构设计都是耍流氓,希望大家有收获,求

展开阅读全文

求助:.net的session究竟怎么玩?

08-17

原来开发的网站是ASP的,后来写了几个程序是ASP.NET(C#)的,要加到原来的网站里面。据我的了解asp和asp.net的session是不可以共享的。rn于是我的解决方法是rn 1:用asp.net写了一个A.ASPX,目的是在asp页面下调用A,并将asp的session同时传给A.ASPX。rn 我是在asp菜单页面上调用了A.ASPXrn %>rn rn rn ">rn rn rn <%rn A.ASPX.CS里面的内容如下:rn private void Page_Load(object sender, System.EventArgs e)rn rn if (!IsPostBack)rn rn string userid="";rn Session["userid"]=null;rn if(Request.QueryString["loginid"]!=null && Request.QueryString["loginid"]!="")rn rn userid=Request.QueryString["loginid"].ToString();rn Session["userid"]=userid;rn //Response.Write(" ");rn rn rn rn rn 2:然后我在其他的asp.net的页面中增加如下判断rn private void Page_Load(object sender, System.EventArgs e)rn rn if (Session["userid"] == null || Session["userid"].ToString() == "") rn rn rn Response.Redirect("errsms.aspx");rn rn elsern rn if(!this.IsPostBack)rn rn ......rn rn rn rn rn 问题: 在1步完成时,我确实可以获得.net的session。但是在2时是就有问题了。。rn 2步问题主要如下:rn a.有的时候可以获得session值,有的时候有没有获得session值。rn b.某个aspx页面获得session值后,执行了查询等操作后,session值就丢掉了。rn c.session不是很稳定的感觉。rn rn 请各位帮忙,找一下问题所在或给俺提出一个更好的方法。rn 3Q!3Q!3Q!3Q!3Q!rn rnrn rn 论坛

没有更多推荐了,返回首页