CAP理论常伴随着分布式架构。由于传统的单机架构不再用于分布式架构,多机需要冗余数据来提供可靠的服务,因此会有分区容忍度P。
在复制数据的同时,冗余数据伴随着可用性A 与强一致性C的问题。选择最终一致性是停止可用性达到强一致性还是保持可用性。通常选择后者。
其中 zookeeper 和 eureka分别是注册中心CP AP 两种实践。它们都提供服务注册中心的功能。建议使用应用程序。不强迫数据的强一致性,以实现数据的最终一致性。
1 eureka AP服务注册中心的数据是可用的服务节点返回(ip+端口号) 服务A开设了0-90个服务节点,服务B需要调用服务A,两次查询返回0-8,1-9 不一致的数据。影响是0 和9 节点负载不平衡
只要注册中心在 SLA 承诺的时间(例如 1s 内部)将数据收敛到一致状态(即满足最终一致性),流量将很快趋于统计意义上的一致性,因此注册中心在生产实践中以最终一致的模型设计完全可以接受。
eureka 保证可用性,实现最终一致性。
Eureka的每个节点都是平等的,几个节点挂断不会影响正常节点的工作,剩下的节点仍然可以提供注册和查询服务。Eureka的客户端在向Eureka注册或发现连接失败时,会自动切换到其他节点。只要一个Eureka还在,注册服务的可用性就可以保证(保证可用性),但发现的信息可能不是最新的(不保证强一致性),说明Eureka不符合强一致性,但最终一致性还是会保证的。
2 zookeeper CPzookeper在选举leader时会停止服务,直到选举成功后才会再次提供外部服务。这时候说明服务不可用。但是选举成功后,由于一主多从的结构,zookeper此时仍然是一个高度可用的注册中心,只有在优先保证一致性的前提下,zookeper才会考虑可用性。
2.1 zookeeper 应用场景- 感知消息队列异步操作后的结果
- 分布式锁
- 元数据 或配置中心 如 dubbo 和Kafka一起 都需要zookepererer
dubbo 也可以不使用zookeperer 采用直接连接提供的方式,但限制了分布式扩展。
- HA高可用
- 主备切换 (两种服务分别为主备,备用平时不提供服务。主的挂了,备用顶作为新主。当原主恢复时,作为新备用)
选型依据:
粗粒度分布式锁,分布式选主,主备高可用切换不需要高 TPS 支持场景起着不可替代的作用,这些需求往往集中在大数据、离线任务等相关业务领域,因为大数据领域注重数据集的划分,大部分时间分为多个任务和流程 / 线程并行处理这些数据集,但总有一些点需要统一协调这些任务和过程,这时候就是 ZooKeeper 用武之地发挥着巨大的作用。
但在交易场景交易链接中,在主要业务数据访问、大规模服务发现、大规模健康监测等方面存在自然缺陷,应尽量避免在这些场景中引入 ZooKeeper,应用于阿里巴巴的生产实践 ZooKeeper 在申请使用时,应进行严格的场景、容量、SLA 评估需求。
因此可以使用 ZooKeeper,但大数据请向左,交易向右,分布式协调向左,服务发现向右。
2.2 不建议使用zookeperereper 场景及原因不建议使用zookeperereper 原因是当它不满足A的影响时。
当机房 3 网络分区出现 (Network Partitioned) 当时,机房 3 在互联网上,它已经成为一个孤岛,我们知道虽然整体 ZooKeeper 服务是可用的,但节点 ZK5 不能写,因为联系不上 Leader。
也就是说,此时机房 3 的应用服务 svcB 新部署、重启、扩容或缩容是不可能的,但从网络和服务调用的角度来看,机房 3 的 svcA 虽然机房不能调用 1 和机房 2 的 svcB, 但是与机房 3 的 svcB 之间的网络显然是 OK 是的,为什么不让我调用本机房的服务呢?
现在因为注册中心本身为了保护脑裂纹 (P) 下面的数据一致性(C)放弃可用性,导致同一机房的服务无法调用,这是绝对不允许的!可以说,在实践中,注册中心不能因为任何原因破坏服务本身的连通性,这是注册中心设计应遵循的铁律
2.3 zookeeper 的拓展ZooKeeper 写作不是可扩展的,水平扩展问题不能通过添加节点来解决。
要想在 ZooKeeper 在解决服务规模增长问题的基础上,实践中可以考虑的一种方法是找到整理业务的方法,垂直划分业务领域,并将其划分为多个领域 ZooKeeper 注册中心,但作为一个提供一般服务的平台组织,由于缺乏服务能力,根据技术指挥棒划分管理业务真的可行吗?
而且,由于注册中心本身的原因(能力不足),这违反了服务的可连通性。举个简单的例子,1 搜索业务,1 地图业务,1 大型文化娱乐业务,1 一个游戏业务,他们之间的服务应该老死不相往来吗?也许今天是肯定的,那么明天呢,1 年后呢,10 年后呢?谁知道未来要打通几个业务领域,做什么奇妙的业务创新?注册中心作为基础服务,不能预测未来不会妨碍业务服务对未来固有的联通需求。
2.4 zookeeper 持久存储ZooKeeper 的 ZAB 协议将在每个请求中编写每个请求 ZooKeeper 保持在节点上写一个事务日志,并定期使用内存数据镜像(Snapshot)到磁盘保证数据的一致性和持久性,以及停机后的数据可以恢复,这是一个很好的特点,但我们需要问,在服务发现场景中,其核心数据 - 实时健康服务的地址列表不需要持久的数据
需要持久存储的地方是一个完整的生产可用的注册中心。除了服务的实时地址列表和实时健康状况外,还将存储一些服务元数据信息,如服务版本、分组、数据中心、权重、权利识别策略信息、service label 等元信息,需要持久存储,注册中心应提供检索这些元信息的能力。
2.5 容灾能力若注册中心(Registry)本身完全停机,服务A 调用 服务B 链路应该受到影响吗?
是的,不应该受到影响。
服务呼叫(请求响应流)链路应弱依赖注册中心,必要时必须依赖注册中心,如服务发布、机器上下、服务扩展等。
这就要求注册中心仔细设计自己提供的客户端。客户端应该有一种手段,当注册中心服务完全不可用时,比如设计客户端缓存数据机制(我们称之为) client snapshot)这是一种有效的手段。此外,注册中心 health check 机制也要精心设计,这样在这种情况下就不会出现推空等情况。
ZooKeeper 本地客户端没有这种能力,所以使用 ZooKeeper 当我们实现注册中心时,我们必须问自己,如果我们把它放在一边 ZooKeeper 所有节点都被杀死了。您生产的所有服务调用链路能不受任何影响吗?此外,故障演练应定期进行。
zookeeper 的健康检查使用 ZooKeeper 作为服务注册中心,经常使用服务健康检测 ZooKeeper 的 Session 活性 Track 机制 以及结合 Ephemeral ZNode 简单来说,机制就是将服务的健康监测绑定在一起 ZooKeeper 对于 Session 健康监测方面,或者绑定在 TCP 长链接活性探测。
这在很多情况下也会导致致命的问题,ZK 与服务提供者之间的机器 TCP 当长链接活性检测正常时,服务是否健康?答案当然是否定的!注册中心应提供更丰富的健康监测方案,服务健康的逻辑应向服务提供商定义,而不是一刀切 TCP 活性检测!
健康检测的基本设计原则之一是尽可能真实地反馈服务本身的真实健康状况,否则不敢被服务调用者相信的健康状况判断结果不如没有健康检测好。
扫码二维码
获得更多精彩
Java乐园