半岛bandao体育(中国)官方网站

BOB半岛APP:硬核上了12张图,对三层缓存架构

日期:2024-07-01 22:39 / 作者:zoc7RcITctunhMtq7EzA
进行了一番解析。首先,由前述

我们提到,Eureka注册中心的服务器端采用了三级缓存来存储注册信息,以便通过快速的缓存读取来提升系统性能。 让我们仔细看一下:

一级缓存:只读缓存 readOnlyCacheMap,使用了ConcurrentHashMap来存储数据。等同于数据存储库。

二级缓存:包括读写缓存readOnlyCacheMap和Guava缓存。在Redis的主从架构中,它相当于主节点,可以进行读写操作。三级缓存:本地注册表(registry),ConcurrentHashMap 数据结构。类似于 Redis 主从结构中的从节点,主要负责处理读操作。

通过查看图表,我们可以更清晰地了解,具体如下:

有三种不同类型的缓存

此外,ConcurrenthashMap也是一种Map 结构,它同样采用键值对的方式进行存储,具体如下:

在本文中,悟空哥将带领大家深入了解Eureka的缓存架构。通过学习本文,我们也能够借鉴Eureka的缓存设计思想,并将其运用到我们的项目中。

其次,我们来分析一下 Eureka 源代码,实际上并不难理解,接下来将会进行解释。在搜索时,默认会首先查找只读缓存。如果没有,就从读写缓存中查找。如果找到了,就更新只读缓存,并返回那个找到的缓存。如果找不到,就从本地缓存的注册表中加载出来。

引发了三个问题:

(1)三级缓存数据是如何产生的?如何更新缓存数据?缓存何时会失效?

三、我们先来讨论一下本地缓存,它是指被定义为 ConcurrentHashMap 数据结构的 registry,之前已经进行了详细讲解。当客户端发起注册请求时,会将注册信息存储在注册表中。请参考以下代码示例:

registry.putIfAbsent(app) 

putIfAbsent 方法表示如果存在相同的 key,则不会放入值。 如果键对应的值已存在,则返回现有值,而不会替换它。调用putIfAbsent方法后,将客户端的注册信息放入了注册表中。我们再来讨论一种缓存结构:读写缓存。四、读写缓存是指能够同时进行读取和写入操作的缓存。读是为了给只读缓存提供读取操作。进行更新操作,将缓存数据同步更新至自己的Map中。您可以从以下几个方面逐一解答:写缓存的工作原理、写缓存的代码实现、过期策略原理和源码实现。4.1简要介绍了写缓存的原理和源代码。最初我认为当缓存读取不到时会去查询数据库。找了半天都找不到读取数据库的地方。然后我就使用 IDEA 工具搜索 readOnlyCacheMap 的使用位置,终于找到了它的使用地方。使用的是Guava Cache工具类来进行读写缓存,这篇不会深入讨论。简单地说,当访问读写缓存时,如果缓存中不存在该 key,则需要从本地查找,找到后再放入缓存中。先调用方法 x,然后再执行抽象方法 load(key),其功能是在读写缓存中未找到时,从本地registry缓存中获取。读写缓存过期时可以分为两种:定时过期和实时过期。因为上面的代码已经规定了定时过期的时间间隔,所以我们先来讨论定时过期的问题。4.2 在构建该读写缓存时,可以设定一个定时过期的间隔,当时间到达时整个读写缓存会过期。根据以下代码,读写缓存将在180秒后定时过期。以写入后180秒过期 4.3即时过期 当新服务实例注册、下线或发生故障时,将使相应服务实例的缓存过期。如下图所示,顶部是注册中心,底部的三个则为服务实例。服务实例发生注册、下线或故障时,注册中心会及时感知,并自动更新读写缓存中对应的服务实例信息。4.4 实时的过期源码是

4.4。我们再从源码层面来看一下读写缓存过期的源码。调用了 invalidateCache 方法,使其过期。

文件路径:com/netflix/eureka/registry/AbstractInstanceRegistry.java

五、只读缓存 5.1 定时更新

只读缓存 Map,拥有定时更新机制,每隔 30 秒会更新只读缓存中的部分 key。它会遍历它的所有注册信息,然后将其与读写缓存进行比对,如果注册信息不一致,则用读写缓存的数据替换。下面是

的源代码,其中包含一个定时调度任务,每隔 30 秒执行一次。5.2 版本更新。另外,当客户端获取注册信息时,会首先读取只读缓存。如果只读缓存中没有相应信息,将从读写缓存中查找。一旦找到,就会将其放入只读缓存中。如果读写缓存中不存在数据,就从本地注册表中加载数据至读写缓存,然后返回注册表信息。

在这里,大家可能会有一个疑问:既然这个缓存被称为只读缓存,为什么还可以被更新,理应是不可改变的才对吗?实际上这里的不变是针对客户端而言的。客户端在获取注册表信息时,首先访问的是只读缓存,类似于数据库或Redis的主从架构,其中主节点负责读写,从节点负责读取。接着,系统会将主节点的信息同步到从节点。大家都理解了吗?六、缓存相关配置
接下来我们将了解一下 Eureka 服务器的缓存配置有哪些。在Eureka服务器中,是否已启用只读响应缓存功能,以便客户端获取注册信息时首先从只读缓存中获取?如果条件为假,则直接从读写缓存中获取。默认值是true。默认的只读缓存更新间隔时间为 30 秒,用于定期将读写缓存同步到只读缓存。缓存可能引发的问题在于三级缓存的性能提升表面看起来是可行的。然而,这也可能会带来其他问题,例如缓存不同步的问题。每当

只读缓存每30秒刷新一次时,与读写缓存可能导致数据不一致,在30秒内客户端获得的注册表信息会有一定滞后。在使用 Eureka 集群时,缓存不一致问题更加显著,不同节点之间可能导致只读缓存数据不一致,因此 Eureka 仅能确保高可用性,而不能保证强一致性,即保证了 AP 而不保证 CP,另外我们还可以选择强一致性的注册中心,比如 Zookeeper、Nacos,这将是接下来要讨论的议题。如何解决不一致的问题?在服务端,我们可以调整只读缓存的刷新时间间隔,默认为30秒。如果时间太短,例如15秒,更新频率过高可能会给Eureka带来性能问题。在服务端,我们可以考虑关闭只读缓存读取注册表信息,而让Eureka客户端直接从读写缓存中获取。

八、总结

BOB半岛娱乐

Eureka Server注冊表的三级缓存架构

。这篇文章介绍了Eureka注册中心服务端的三层缓存架构, 分别是registry、readOnlyCacheMap和readWriteCacheMap,用于存储服务注册信息。每隔30秒,注册信息从读写缓存更新到只读缓存。在默认情况下,客户端在读取注册表时,首先从只读缓存中读取,如果没有,则从读写缓存中读取,如果还是没有,则从本地注册表中读取。每隔180秒,缓存中的读写操作将会自动过期。服务实例在注册、下线或发生故障时,将会立即更新读写缓存的过期时间。引入多级缓存可能导致缓存不一致的问题。 参考链接:

www.passjava.cn

《深度解析微服务架构》BOB半岛新版

 

Eureka源码

 

硬核上了12张图,对三层缓存架构

BOB半岛平台

BOB半岛下载


BOB半岛平台