您当前的位置:首页 > 电脑百科 > 程序开发 > 架构

微服务架构中缓存模式

时间:2019-09-27 13:22:45  来源:  作者:

在微服务世界中,每个人都使用缓存,缓存无处不在。缓存可以提高性能,减少后端负载,或者减少down机时间。有许多方法可以配置系统中的缓存,缓冲应该被放在系统的哪个层上?根据以往成功经验,系统中您应该只在一个地方使用缓存。不应该同时在多个层中组合模式和缓存,例如同样的内容在HTTP层和应用程序级别同时做缓存。这种方法可能导致更多的缓存失效问题,并使您的系统更容易出错,且难于调试。

如果您在一个特定的层上使用缓存,那么您可以选择使用哪种模式。最保守的方法是老式的客户机-服务器(或云)模式,这个问题的正确答案不止一个。您可以将缓存放在每个服务中,或者作为一个完全独立的缓存服务器。您还可以将它放在每个服务的前面,甚至作为属于服务的sidecar容器等等。本文下面,让我们总结一下您在微服务世界多种方式的缓存体系结构。

嵌入式缓存

最简单的缓存模式是嵌入式缓存。

微服务架构中缓存模式

嵌入式缓存

在上图中,流程如下:

1.请求进入负载平衡器。

2.负载均衡器将请求转发给应用程序服务之一。

3.应用程序服务接收请求,并检查是否相同的请求已经执行(并存储在缓存)◦

如果是,然后返回缓存数据。反之,则执行业务操作,并把结果数据存储在缓存中,并返回结果数据。

业务操作可以是任何值得缓存的内容。例如,执行计算、查询数据库或调用外部web服务等。

这种缓存逻辑非常简单,我们可以使用内置的数据结构或一些缓存库(如Guava cache)为其快速编写代码。我们还可以将缓存放在应用程序层中,并使用大多数web框架提供的缓存功能。例如,对于Spring,添加缓存层只需要向方法添加@Cacheable注释。

嵌入式缓存方法有一个严重的问题。假设有一个向我们的系统发出的请求,它第一次被转发到顶部的应用程序服务A。然后,同样的请求出现,但这一次负载平衡器将其转发给底部的应用程序服务B。这种情况下,我们收到了两次相同的请求,但是必须执行两次业务逻辑,因为图中的两个缓存是分别完成的。为了处理这样的问题,可以使用嵌入分布式缓存。

嵌入分布式缓存

微服务架构中缓存模式

 

嵌入式分布式缓存仍然是嵌入式缓存的模式;但是,这一次我们将使用Hazelcast(Hazelcast 是由Hazelcast公司开发和维护的开源产品,可以为基于jvm环境运行的各种应用提供分布式集群和分布式缓存服务)而不是默认的非分布式缓存库。从现在开始,所有缓存(嵌入到所有应用程序中)形成一个分布式缓存集群。因为Hazelcast是用JAVA编写的,所以您可以将它与Spring一起使用;

您需要做的就是添加以下CacheManager配置。

微服务架构中缓存模式

 

通过这几行代码,我们让Spring为它提供的所有缓存功能使用Hazelcast。

使用嵌入式缓存(分布式和非分布式)很简单,因为它不需要任何额外的配置或部署。而且,您总是可以获得低延迟的数据传输,因为缓存在物理上运行在相同的JVM中。稍后我们将更仔细地研究这个解决方案的优缺点。

下面让我们介绍另一个完全不同的缓存模式,客户机-服务器。

客户端/服务器式缓存

微服务架构中缓存模式

 

此时,图中所示流程如下:

1.请求进入负载均衡组件并被转发到应用程序服务

2.应用程序使用缓存客户机连接到缓存服务器

3.如果没有找到值,则执行通常的业务逻辑,缓存值并返回响应

该体系结构与经典的数据库体系结构相似。我们有一个中心服务器(或者更准确地说是一组服务器),应用程序连接到该服务器。如果我们将客户机-服务器模式与嵌入式缓存进行比较,主要有两个区别:

•首先,缓存服务器在我们的体系结构中是一个单独的单元,这意味着我们可以单独管理它(向上/向下伸缩、备份、安全)。然而,这也意味着它通常需要单独的项目事务处工作(甚至单独的项目事务处团队)。

•第二个区别是应用程序使用缓存客户端库与缓存通信,这意味着我们不再局限于基于jvm的语言。有一个定义良好的协议,服务器部分的编程语言可以与客户端部分不同。这实际上是许多缓存解决方案(如redis或Memcached)仅为其部署提供这种模式的原因之一。

我之前提到过,嵌入式缓存和客户机-服务器缓存的第一个区别是前者是单独管理的。一个单独的Ops团队甚至可以管理它,或者您可以更进一步,将管理部分转移到云计算中。

云端缓存

微服务架构中缓存模式

 

架构而言,云类似于客户机-服务器,不同之处在于服务器部分被移到组织之外,由云提供商管理,因此您不必担心所有的组织问题。

如果您对某个示例感兴趣,可以在Hazelcast云平台上创建一个Hazelcast集群,然后,您可以在这里找到一个完整的客户机应用程序。

最有趣的部分是Spring配置:

@Bean
CacheManager cacheManager() {
 ClientConfig clientConfig = new ClientConfig();
 clientConfig.getNetworkConfig().getCloudConfig()
 .setEnabled(true)
 .setDiscoveryToken("KSXFDTi5HXPJGR0wRAjLgKe45tvEEhd");
 clientConfig.setGroupConfig(new GroupConfig("test-cluster", "b2f9845"));
 return new HazelcastCacheManager(
 HazelcastClient.newHazelcastClient(clientConfig));
}

使用客户机-服务器模式很简单,使用云模式更简单。它们都带来了类似的好处,比如将缓存数据与应用程序分离、独立管理(向上/向下扩展、备份)以及使用任何编程语言的可能性。然而,有一件事变得更加困难——延迟。对于嵌入式模式,缓存始终与应用程序位于同一台机器上(甚至在同一JVM中)。然而,当服务器部分被分离时,我们现在需要考虑它的物理位置。最好的选择是使用相同的本地网络(或者在云解决方案中使用相同的VPC)。

现在,让我们转移到一个新的稍微不寻常的模式,缓存作为一个边车。

边车式缓存(Sidecar

微服务架构中缓存模式

 

上面的图表是特定于Kubernetes的,因为Sidecar模式主要出现在Kubernetes环境中(但不限于)。在Kubernetes中,部署单元称为POD。这个POD包含一个或多个容器,这些容器总是部署在相同的物理机器上。

通常,一个POD只包含一个容器和应用程序本身。然而,在某些情况下,您不仅可以包含应用程序容器,还可以包含一些提供附加功能的附加容器。这些容器称为边车容器。

流程如下:

1.请求到达Kubernetes服务(负载平衡器)并被转发到其中一个吊舱。

2.请求到达应用程序容器,应用程序使用缓存客户机连接到缓存容器(从技术上讲,缓存服务器总是在localhost上可用)。

这个解决方案混合了嵌入式模式和客户机-服务器模式。

它类似于嵌入式缓存,因为:

•缓存始终与应用程序位于同一台机器上(低延迟)。

•资源池和管理活动在缓存和应用程序之间共享。

•缓存集群发现不是问题(它总是在本地主机上可用)。

它也类似于客户机-服务器模式,因为:

•应用程序可以用任何编程语言编写(它使用缓存客户端库进行通信)。

•缓存和应用程序有一些隔离。

现在让我们讨论一个完全不同的模式,反向代理。

反向代理缓存

微服务架构中缓存模式

 

到目前为止,在前面每个场景中,应用程序都清楚自己使用了缓存。然而,这一次,我们将缓存部分放在应用程序前面,所以流程如下:

1.请求进入负载平衡器。

2.负载均衡器检查这样的请求是否已经缓存。

3.如果是,则返回响应,而不将请求转发给应用程序。

这样的缓存解决方案是基于协议级别的,所以在大多数情况下,它是基于HTTP的,这有一些好的和坏的含义:

•好的方面是,您可以将缓存层指定为配置,因此不需要更改应用程序中的任何代码。

•不好的是,您不能使用任何基于应用程序的代码来使缓存失效,因此失效必须基于超时(以及标准HTTP TTL、ETag等)。

Nginx提供了成熟的反向代理缓存解决方案;然而,缓存中保存的数据不是分布式的,不是高可用性的,数据存储在磁盘上。

我们可以对反向代理模式做的一个改进是将HTTP反向代理注入到sidecar中。你可以这样做:

反向代理边车

微服务架构中缓存模式

 

同样,当涉及到Sidecar时,该图仅限于Kubernetes环境。流程如下:

1.请求进入Kubernetes服务(负载平衡器)并被转发到其中一个pod。

2.在POD中,接收请求的是反向代理缓存容器(而不是应用程序容器)。

3.反向代理缓存容器检查这样的请求是否已经缓存。

4.如果是,则发送缓存的响应(甚至不将请求转发给应用程序容器)。

应用程序容器甚至不知道缓存的存在。考虑一下本文开头介绍的微服务系统。使用此模式,我们可以查看整个系统并指定(在Kubernetes配置文件中)应该缓存服务2v1和服务1。

前还没有成熟的HTTP反向代理缓存Sidecar解决方案,然而,我相信它会变得越来越流行,因为一些项目已经在积极地进行一些稳定的实现。

优点和缺点

我们提到了许多可以在微服务系统中使用的缓存模式。

优缺点列表:

微服务架构中缓存模式

 



Tags:微服务架构 缓存模式   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
在微服务世界中,每个人都使用缓存,缓存无处不在。缓存可以提高性能,减少后端负载,或者减少down机时间。有许多方法可以配置系统中的缓存,缓冲应该被放在系统的哪个层上?根据以往...【详细内容】
2019-09-27  Tags: 微服务架构 缓存模式  点击:(127)  评论:(0)  加入收藏
▌简易百科推荐
为了构建高并发、高可用的系统架构,压测、容量预估必不可少,在发现系统瓶颈后,需要有针对性地扩容、优化。结合楼主的经验和知识,本文做一个简单的总结,欢迎探讨。1、QPS保障目标...【详细内容】
2021-12-27  大数据架构师    Tags:架构   点击:(5)  评论:(0)  加入收藏
前言 单片机开发中,我们往往首先接触裸机系统,然后到RTOS,那么它们的软件架构是什么?这是我们开发人员必须认真考虑的问题。在实际项目中,首先选择软件架构是非常重要的,接下来我...【详细内容】
2021-12-23  正点原子原子哥    Tags:架构   点击:(7)  评论:(0)  加入收藏
现有数据架构难以支撑现代化应用的实现。 随着云计算产业的快速崛起,带动着各行各业开始自己的基于云的业务创新和信息架构现代化,云计算的可靠性、灵活性、按需计费的高性价...【详细内容】
2021-12-22    CSDN  Tags:数据架构   点击:(10)  评论:(0)  加入收藏
▶ 企业级项目结构封装释义 如果你刚毕业,作为Java新手程序员进入一家企业,拿到代码之后,你有什么感觉呢?如果你没有听过多模块、分布式这类的概念,那么多半会傻眼。为什么一个项...【详细内容】
2021-12-20  蜗牛学苑    Tags:微服务   点击:(9)  评论:(0)  加入收藏
我是一名程序员关注我们吧,我们会多多分享技术和资源。进来的朋友,可以多了解下青锋的产品,已开源多个产品的架构版本。Thymeleaf版(开源)1、采用技术: springboot、layui、Thymel...【详细内容】
2021-12-14  青锋爱编程    Tags:后台架构   点击:(21)  评论:(0)  加入收藏
在了解连接池之前,我们需要对长、短链接建立初步认识。我们都知道,网络通信大部分都是基于TCP/IP协议,数据传输之前,双方通过“三次握手”建立连接,当数据传输完成之后,又通过“四次挥手”释放连接,以下是“三次握手”与“四...【详细内容】
2021-12-14  架构即人生    Tags:连接池   点击:(17)  评论:(0)  加入收藏
随着移动互联网技术的快速发展,在新业务、新领域、新场景的驱动下,基于传统大型机的服务部署方式,不仅难以适应快速增长的业务需求,而且持续耗费高昂的成本,从而使得各大生产厂商...【详细内容】
2021-12-08  架构驿站    Tags:分布式系统   点击:(23)  评论:(0)  加入收藏
本系列为 Netty 学习笔记,本篇介绍总结Java NIO 网络编程。Netty 作为一个异步的、事件驱动的网络应用程序框架,也是基于NIO的客户、服务器端的编程框架。其对 Java NIO 底层...【详细内容】
2021-12-07  大数据架构师    Tags:Netty   点击:(17)  评论:(0)  加入收藏
前面谈过很多关于数字化转型,云原生,微服务方面的文章。虽然自己一直做大集团的SOA集成平台咨询规划和建设项目,但是当前传统企业数字化转型,国产化和自主可控,云原生,微服务是不...【详细内容】
2021-12-06  人月聊IT    Tags:架构   点击:(23)  评论:(0)  加入收藏
微服务看似是完美的解决方案。从理论上来说,微服务提高了开发速度,而且还可以单独扩展应用的某个部分。但实际上,微服务带有一定的隐形成本。我认为,没有亲自动手构建微服务的经历,就无法真正了解其复杂性。...【详细内容】
2021-11-26  GreekDataGuy  CSDN  Tags:单体应用   点击:(35)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条