1 复制方式
分布式系统的数据在多个副本之间的复制方式,主要有主从复制和对等复制。Eureka 采用的就是 Peer to Peer 模式,消息广播方式来实现一致性。
- 主从复制
就是 Master-Slave 模式,有一个主副本,其他为从副本,所有写操作都提交到主副本,再由主副本更新到其他从副本。
写压力都集中在主副本上,是系统的瓶颈,从副本可以分担读请求。
- 对等复制(广播模式)
就是 Peer to Peer 模式,副本间不分主从,任何副本都可以接收写操作,然后每个副本间互相进行数据更新。
对等复制模式,任何副本都可以接收写请求,不存在写压力瓶颈,但各个副本间数据同步时可能产生数据冲突。
2 Eureka一致性
2.1 消息广播
1、 广播描述
当 Eureka Server 收到客户端的注册、下线、心跳续约请求时,通过 PeerEurekaNode 向其余的服务器进行消息广播,如果广播失败则重试,直到任务过期后取消任务,此时这两台服务器之间数据会出现短暂的不一致。
注意: 虽然消息广播失败,但只要收到客户端的心跳,仍会向所有的服务器(包括失联的服务器)广播心跳任务。
注意:因为采用广播同步,所以Eureka保证的是AP
2、 复制冲突
比如 server A 向 server B 发起同步请求,如果 A 的数据比 B 的还旧,B 不可能接受 A 的数据,那么 B 是如何知道 A 的数据是旧的呢?这时 A 又应该怎么办呢?
数据的新旧一般是通过版本号来定义的,Eureka 是通过 lastDirtyTimestamp
这个类似版本号的属性来实现的。
lastDirtyTimestamp
是注册中心里面服务实例的一个属性,表示此服务实例最近一次变更时间。
比如 Eureka Server A 向 Eureka Server B 复制数据,数据冲突有2种情况:
(1)A 的数据比 B 的新,B 返回 404,A 重新把这个应用实例注册到 B。
(2)A 的数据比 B 的旧,B 返回 409,要求 A 同步 B 的数据。
2.2 hearbeat 心跳,即续约操作
来进行数据的最终修复,因为节点间的复制可能会出错,通过心跳就可以发现错误,进行弥补。
3 稳定性
3.1 实例重启
Spring Cloud Eureka 启动时,在初始化 EurekaServerBootstrap#initEurekaServerContext 时会调用 PeerAwareInstanceRegistryImpl#syncUp 从其它 Eureka 中同步数据。
3.2 脑裂
1. 脑裂时间很短,一切正常
2. 客户端实例已经自动过期,需要在监听到心跳之后重新进行注册
Eureka Server 默认每 30s 发送心跳包,90s 未收心跳则删除。这个清理过期实例的线程,每 60s 执行一次。
4 参考
SpringCloud 注册中心 Eureka 集群是怎么保持数据一致的? https://cloud.tencent.com/developer/article/1526983
Eureka 系列(02)Eureka 一致性协议