当前位置:网站首页>图文详述Eureka的缓存机制/三级缓存
图文详述Eureka的缓存机制/三级缓存
2022-08-01 19:26:00 【秃秃爱健身】
前言
1、为什么说Eureka是CAP理论中的AP?
从CAP理论看,Eureka是一个AP系统,其优先保证可用性(A)和分区容错性§,不保证强一致性,但能做到最终一致性。
- 因为只要集群中
任意一个实例不出现问题,Eureka服务就是可用的;即Eureka Client 在向某个 Eureka Server 注册时,如果发现连接失败,则会自动切换至其它节点; - 另外Eureka集群中没有主从的概念,各个节点都是平等的,节点间采用Replicate异步的方式来同步数据;
也正因为Eureka 本身不保证数据的强一致性,所以在架构又设计了很多缓存。
2、为什么要设计那么多缓存(三级缓存)?
这个和MySQL用主从做读写分离很相似,数据库层面的读写分离是为了分摊主数据库的读压力;而Eureka的三级缓存也是为了做读写分离,使写操作不阻塞读操作。
- 因为在
写的时候,线程会持有ConcurrentHashmap相应Hash桶节点对象的锁,阻塞同一个Hash桶的其他读线程。 - 这样可以有效的降低读写并发,避免读写读写争抢资源所带来的压力。
那么加了那么多缓存,如何保证缓存数据的最终一致性?
我们下面就详细聊一下Eureka是如何做的。
缓存机制
Eureka Server中有三个变量用来保存服务注册信息,分别是:registry、readWriteCacheMap、readOnlyCacheMap;默认情况下定时任务每30s将二级缓存readWriteCacheMap同步至三级缓存readOnlyCacheMap;
1、Eureka Server每60s清理超过90s * 2(官方彩蛋)未续约的节点;
2、Eureka Client每30s从readOnlyCacheMap更新服务注册信息;
3、UI界面则从registry获取最新的服务注册信息。
1、三级缓存分别是什么?
| 缓存 | 缓存类型 | 所处类 | 概述 |
|---|---|---|---|
| registry 一级缓存 | ConcurrentHashMap | AbstractInstanceRegistry | 实时更新,又名注册表,UI界面从这里获取服务注册信息; |
| readWriteCacheMap 二级缓存 | Guava Cache(LoadingCache) | ResponseCacheImpl | 实时更新,缓存时间180秒; |
| readOnlyCacheMap 三级缓存 | ConcurrentHashMap | ResponseCacheImpl | 周期更新,默认每30s从二级缓存readWriteCacheMap中同步数据更新; Eureka Client默认从这里获取服务注册信息,可配为直接从readWriteCacheMap获取 |
二级缓存又称读写缓存、三级缓存又称只读缓存;
1)Eureka Server缓存相关配置
| 配置名 | 默认值 | 概述 |
|---|---|---|
| eureka.server.useReadOnlyResponseCache | true | Client从readOnlyCacheMap更新数据,false则跳过readOnlyCacheMap直接从readWriteCacheMap更新 |
| eureka.server.responsecCacheUpdateIntervalMs | 30000 | readWriteCacheMap更新至readOnlyCacheMap的周期,默认30s |
2、缓存之间的数据同步
AbstractInstanceRegistry类中的registry字段为注册表、并与保存一级缓存(实时最新数据);ResponseCacheImpl类中的readWriteCacheMap字段和readOnlyCacheMap字段分别表示二级缓存和三级缓存;下面我们就围绕这两个类、三个字段的数据同步展开讨论。
1)注册一个服务实例
Eureka Server中做的操作:
向注册表registry中写入服务实例信息,并使得二级缓存失效;

Eureka client第一次向Eureka Server注册服务或者发送心跳续约时,会进去到Eureka Serve中ApplicationResource#addInstance()方法中:
最终进入到AbstractInstanceRegistry#register()方法中,往其registry字段中添加服务注册信息:
这里以服务注册为例,我们知道了registry的数据来源;
注意,在做服务注册的最后会将二级缓存清空/失效;
下面我们接着来看一下Eureka的二级缓存和三级缓存是如何运作的?
2)二级/三级缓存什么时候初始化?
Eureka Server启动的时候会根据SpringBoot自动装配的特性,初始化EurekaServerContext接口的实现类DefaultEurekaServerContext;在DefaultEurekaServerContext初始化时会执行构造器后置逻辑initialize(),其中会初始化注册中心;
接着进入到PeerAwareInstanceRegistry接口的实现类PeerAwareInstanceRegistryImpl#init()方法中,其中会通过调用initializedResponseCache()方法初始化二级/三级缓存;
3)二级/三级缓存初始化都做了什么?
这里可以看到initializedResponseCache()方法中直接new了一个ResponseCacheImpl类;
我们接着进入到ResponseCacheImpl类中,看一下它的构造函数:
总的来说,在初始化ResponseCacheImpl类时:
- 会设置初始化二级缓存
readWriteCacheMap(过期时间180s),设置二级缓存往三级缓存readOnlyCacheMap同步的时间间隔(默认30s)。 - 设置是否使用三级缓存(默认使用),如果使用则启动一个定时任务,默认每隔30s从二级缓存中同步数据到三级缓存(只更新三级缓存中已存在的key);
4、发现/寻找一个服务
针对Eureka Client和UI界面,他们读取的服务注册信息的方式略有不同:
- 针对Eureka Client:
1、如果使用只读缓存(三级缓存)<默认使用>,则先从只读缓存中获取;如果获取不到,则从读写缓存(二级缓存)中获取,并将数据缓存到只读缓存;
2、不使用只读缓存,则直接从读写缓存中获取;如果获取不到则触发guava的回调函数从注册表registry中同步数据(即从一级缓存 – 注册表registry中取)- 而对于UI界面,则是实时从一级缓存(注册表registry)中取。
对于Eureka Client无论是获取一个Application的信息(入口为ApplicationResource#getApplication())还是获取所有Application的信息(入口为ApplicationsResource#getContainers())都会进入到ResponseCacheImple#get(Key key)方法,然后进过此路径《get(key, shouldUseReadOnlyResponseCache) --> getValue(final Key key, boolean useReadOnlyCache)》最终走到真正从缓存中读取数据的逻辑:

总结
1、Eureka Server 在接收Eureka Client注册的时候,会将读写缓存(二级缓存)清空;
2、Eureka Server启动时会做两件事:
- 会初始化读写缓存(
二级缓存),从注册表registry(一级缓存)中实时加载数据,默认180s过期;- 判定是否使用只读缓存(三级缓存),默认开启;如果使用则开启一个定时任务,默认每30s做一次读写缓存到只读缓存的数据同步;
3、Eureka Client获取服务信息时,默认先从只读缓存获取;获取不到再从读写缓存中获取,并将数据缓存到只读缓存;获取不到,再触发guava的回调函数从注册表中同步(即从一级缓存 – 注册表registry中取)。
1、多级缓存带来的好处?
- 尽可能的避免服务注册出现频繁的读写冲突,写阻塞读;
- 提高Eureka Server服务的读写性能。
面对频繁读写资源争抢、写阻塞读等情况,我可以考虑借鉴Eureka的多级缓存方案做读写分离。
边栏推荐
- 123123123123
- Redis启动时提示Creating Server TCP listening socket *:6379: bind: No error
- 哈哈!一个 print 函数,还挺会玩啊!
- 即时通讯开发移动端弱网络优化方法总结
- Choosing the right DevOps tool starts with understanding DevOps
- 【LeetCode】Day109-the longest palindrome string
- 升哲科技携全域数字化方案亮相2022全球数字经济大会
- Risc-v Process Attack
- 开源视界 | StreamNative 盛宇帆:和浪漫的人一起做最浪漫的事
- DAO开发教程【WEB3.0】
猜你喜欢

Shell script topic (07): file from cfs to bos

What should I do if the Win11 campus network cannot be connected?Win11 can't connect to campus network solution

BN BatchNorm + BatchNorm的替代新方法KNConvNets

【周赛复盘】LeetCode第304场单周赛

网站建设流程

通配符 SSL/TLS 证书

Win11校园网无法连接怎么办?Win11连接不到校园网的解决方法

kubernetes - deploy nfs storage class

网络不通?服务丢包?这篇 TCP 连接状态详解及故障排查,收好了~

从普通进阶成优秀的测试/开发程序员,一路过关斩将
随机推荐
百度无人驾驶商业化已“上路”
[Neural Network] This article will take you to easily analyze the neural network (with an example of spoofing your girlfriend)
Fuzzy query in Map pass-by-value and object pass-by-value
No need to crack, install Visual Studio 2013 Community Edition on the official website
硬件大熊原创合集(2022/07更新)
cf:D. Magical Array【数学直觉 + 前缀和的和】
COS User Practice Call for Papers
屏:全贴合工艺之GFF、OGS、Oncell、Incell
Ha ha!A print function, quite good at playing!
What should I do if the Win11 campus network cannot be connected?Win11 can't connect to campus network solution
To drive efficient upstream and downstream collaboration, how can cross-border B2B e-commerce platforms release the core value of the LED industry supply chain?
Gradle系列——Gradle文件操作,Gradle依赖(基于Gradle文档7.5)day3-1
30分钟成为Contributor|如何多方位参与OpenHarmony开源贡献?
Hardware Bear Original Collection (Updated 2022/07)
MySQL开发技巧——并发控制
ThreadLocal讲义
【蓝桥杯选拔赛真题47】Scratch潜艇游戏 少儿编程scratch蓝桥杯选拔赛真题讲解
explain each field introduction
modbus bus module DAM-8082
【Redis】缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存击穿、缓存降级