当前位置: 首页 > 科技观察

进程内缓存,怎么玩?

时间:2023-03-21 13:27:43 科技观察

除了redis/memcache等常见的进程外缓存服务,还有一种常见的缓存玩法,进程内缓存。什么是进程内缓存?答:在站点或服务的进程中缓存一些数据称为进程内缓存。进程内缓存的实现载体,最简单的,可以是一个带锁的Map。或者,可以使用第三方库,例如leveldb。进程内缓存可以存储什么?答:redis/memcache等进程外缓存服务可以存储什么,进程内缓存可以存储什么。如上图,可以存储json数据、html页面、对象。进程内缓存有什么好处?答:与不缓存相比,进程内缓存的优势在于数据读取不再需要访问后端,比如数据库。如上图,整个访问过程经过1、2、3、4四个步骤,如果引入进程内缓存,如上图,整个访问过程只需要经过两个steps1和2,相对于进程外缓存(如redis/memcache),进程内缓存节省了网络开销,所以一来节省了内网带宽,二来响应延迟会更低。进程内缓存的缺点是什么?答:统一缓存服务虽然多了一次网络交互,但仍然是统一存储。如上图所示,站点和服务中的多个节点访问一个统一的缓存服务,数据统一存储,很容易保证数据的一致性。进程内缓存,如上图所示,如果数据缓存在站点和服务的多个节点,数据多份存储,很难保证一致性。如何保证进程内缓存的数据一致性?答:有几种方案可以保证进程内缓存的一致性。第一种解决方案是通过单个节点通知其他节点。如上图所示:写请求发生在server1上。修改了自己的内存数据和数据库中的数据后,可以主动通知其他服务器节点,也可以修改内存数据。这种方案的缺点是一个集群的多个具有相同功能的节点耦合在一起,尤其是节点数量较多时,网状连接关系极其复杂。第二种方案,可以通过MQ通知其他节点。如上图所示,写请求发生在server1上。修改了自己的内存数据和数据库中的数据后,向MQ发送数据变化通知。其他服务器节点订阅MQ消息,也会修改内存数据。这种方案虽然去掉了节点之间的耦合,但是引入了MQ,使得系统更加复杂。对于前两种方案,节点越多,数据冗余副本越多,同时数据更新的原子性越难保证,一致性越难保证。第三种方案,为了避免耦合,降低复杂度,干脆放弃“实时一致性”,每个节点启动一个定时器,定时从后端拉取最新数据,更新内存缓存。脏数据会在节点更新后端数据和其他节点通过定时器更新数据之间读取。为什么不能经常使用进程内缓存?答:在分层架构设计中,有一个规则:站点层和服务层必须是无数据和无状态的,这样节点可以任意添加和水平扩展,数据和状态应该存储在后台。端数据尽可能的存储服务,比如数据库服务或者缓存服务。可见,站点和服务的进程内缓存其实违反了分层架构设计的无状态原则,所以一般不推荐。什么时候可以使用进程内缓存?答:以下几种情况,可以考虑使用进程内缓存。Case1,只读数据,可以认为是在进程启动时加载到内存中。画外音:此时也可以加载数据到redis/memcache,进程外缓存服务也可以解决这类问题。情况2,极高并发,如果透传后端压力极高,可以考虑使用进程内缓存。比如秒杀业务,并发度极高,需要site层阻断流量,可以使用内存缓存。第三种情况,在一定程度上允许数据不一致业务。比如一些统计场景和操作场景,页面对数据一致性要求不高,可以考虑使用进程内页面缓存。最后再次强调,进程内缓存的应用场景没有redis/memcache广泛,所以不要拿来炫耀。更多时候,老老实实使用redis/mc。画外音:嗯,介绍一下技术吧,我不想分散大家的注意力。【本文为专栏作者《58神剑》原创稿件,转载请联系原作者】点此阅读更多该作者好文