本文概览:介绍eureka数据一致性的实现。

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 一致性协议

https://www.cnblogs.com/binarylei/p/11605734.html

分类&标签