分布式系统下的CAP定理

本文参考EricBrewer博客加上自己的理解整理。

CAP定理又被成为布鲁尔定理,是加州大学计算机科学家埃里克·布鲁尔提出来的猜想,后来被证明成为分布式计算领域公认的定理。

分布式系统下的CAP定理

CAP定义,在高并发的场景下要做取舍,在大型集群中分区容错很难保证,一旦要确保容错性,那么就会损失数据一致性和高可用特性。所以可以认为 CAP 的 P 总是成立,剩下的 C 和 A 无法同时做到

; 1 CAP理解

C 一致性(Consistency)

系统由G1,G2两台服务器组成,两台服务器都有一个数据 V,初始值为V0。G1和G2相互可以通信,也可以与客户端通信。如下图

分布式系统下的CAP定理

客户端向G1写入数据,将G1中的V值改成V1,并从G1中读取V的值。目前操作是具备一致的的。如下图

分布式系统下的CAP定理

那么此时如果向G2发起读请求的话,因为数据没有同步,就会得到V的值为V0,实际已经向集群写入了V=V1,此时数据不一致。如下图

分布式系统下的CAP定理

我们可以通过G1将数据同步到G2,这时客户端再去读取,就会解决一致性的问题。如下图

分布式系统下的CAP定理
小结
一致性是指分布式系统中,数据在多节点存在副本,数据如果 一直不修改,在读的时候是不存在问题的,访问哪个节点的数据都一样。可一旦要是发生了 修改,如果数据同步无法在修改的 瞬间广播到所有副本节点那么在读的时候就可能发生 数据脏读

; A 可用性(Availability)

指的是服务是否可用,范围涵盖终端客户访问我们的系统或者是集群内部相互通讯交换数据,也就是说在Client向Server发起请求时,服务器返回了正确的响应,称之为可用,反之为不可用。
这里有一个问题,如果发送请求在很久之后才返回数据,那么算不算可用?
所以要提出访问延迟的概念,在某个时间范围内响应才算可用。
1s法则
1S法则是面向WEB端,H5链路上加载性能 和体验方向上的一个指标,具体指:

  • “强网” (4G/WIFI)下,1秒完全完成页面加载,包括首屏资源,可看亦可用;
  • 3G下1秒完成首包的返回 ;
  • 2G下1秒完成建连。

P 分区容错性(Partition tolerance)

指发生在分布式系统 内部相互访问的通信 网络不可以用,但系统依然正常 对外提供服务。如下图

分布式系统下的CAP定理
上图说明
集群中存在3台节点:server1、server2、server3 。集群内部server1和server3网络不可用,但是server1和server2,server2和server3相互通信是正常的。客户端client1可以与server1和server2通信,客户端client2可以与server2和server3通信。整个集群对于客户端来说不会因为server1和server3之前网络不可用而停止服务。因此我们可以认为集群分区具备容错性。
小结
分区容错性是指分区具有容错性,我们可以尽可能的提高容错性,但是无法避免,如果发生失败,就要在A和C之间做出选择。要么停止系统进行错误恢复,要么继续服务但是降低一致性,所以我们只能保证AP或CP。

; 2 BASE理论

eBay的架构师Dan Pritchett 源于对大规模分布式系统的实践总结,在ACM上发表文章提出BASE理论,BASE理论是对CAP理论的延伸,核心思想是即使无法做到强一致性(StrongConsistency,CAP的一致性就是强一致性),但应用可以采用适合的方式达到最终一致性(Eventual Consitency)。

基本可用(Basically Available)

在分布式系统出现故障的时候,允许损失部分可用性,支持分区失败,即保证核心可用。

软状态(Soft State)

接受一段时间的状态不同步,及中间状态,而改中间状态不影响系统整体可用性。这里的中间状态就是CAP理论中的数据不一致性。

最终一致性(Eventually Consistent)

上面说软状态,然后不可能一直是软状态,必须有个时间期限。在期限过后系统能够保证在没有其他新的更新操作的情况下,数据最终一定能够达到一致的状态,因此所有客户端对系统的数据访问最终都能够获取到最新的值。

3 基于CAP架构选型对比

Zookeeper集群

保证 CP。即任何时刻对zookeeper的访问请求能得到一致性的数据结果,同时系统对网络分割具备容错性,但是它不能保证每次服务的可用性。从实际情况来分析,在使用zookeeper获取服务列表时,如果zk正在选举或者zk集群中半数以上的机器不可用,那么将无法获取数据。所以说,zk不能保证服务可用性。

Redis集群

保证 AP。Redis通过AOF和RDB将数据同步到子节点。如果Master节点挂了,可以很迅速的将Slave提升为Master,尽可能的保证了系统的可用性,但是可能存在数据丢失的问题。所以Redis其实并不适合做分布式锁。

Eureka集群

保证 AP,eureka在设计时优先保证可用性,每一个节点都是平等的,一部分节点挂掉不会影响到正常节点的工作,不会出现类似zk的选举leader的过程,客户端发现向某个节点注册或连接失败,会自动切换到其他的节点,只要有一台eureka存在,就可以保证整个服务处在可用状态,只不过有可能这个服务上的信息并不是最新的信息。

Original: https://www.cnblogs.com/dooor/p/cap.html
Author: Dvomu
Title: 分布式系统下的CAP定理

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/607227/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【socket】基于poll和epoll通信温度上报

    网络socket通信 * – poll函数 – epoll函数 – poll代码实现 – epoll代码实现 poll函数 poll…

    Linux 2023年6月13日
    087
  • Java实现两种队列(数组和链表)

    @date 2022-09-13 17:50*/public class QueueLinked{ private static class Node{E item;Node ne…

    Linux 2023年6月14日
    0121
  • 网站URL如何SEO优化

    前言 本文讲解网站的URL如何进行SEO优化,并在自己的WordPress博客echeverra中优化URL。 起因 对于SEO我了解的并不多,只知道SEO做的好,那么各大搜索网站…

    Linux 2023年6月7日
    088
  • 对比nushell和powershell

    2021-07-17 第一版 有些对比领域缺失,这篇文章会持续更新。 这是一篇对比powershell和nushell的文章。我是powerhsell专家,又是nushell新手,…

    Linux 2023年6月14日
    096
  • K8S部署之VMWare网络拓扑踩坑

    知乎上最近发现一篇好文 图解K8S(01):基于Ubuntu 20.04部署1.23版K8S集群,想着之前 K8S 部署一直不成功,那么就照着这篇文章中说的试一试。结果在实验时遇到…

    Linux 2023年5月27日
    079
  • 条件分支

    条件分支 if-else-fi [root@node1 test]# vim if.sh #!/bin/bash amswer=30 if [ $1 -gt $answer ];t…

    Linux 2023年6月11日
    070
  • 万字长文入门 Redis 命令、事务、锁、订阅、性能测试

    作者:痴者工良 Redis 基本数据类型 Redis 的 Key Redis Key 命名 设置 Key 过期时间 判断键是否存在 搜索 Key 判断键类型 删除键 RESP 协议…

    Linux 2023年5月28日
    089
  • Java基础系列–06_抽象类与接口概述

    抽象类与接口的简单概述 抽象类(1)如果多个类中存在相同的方法声明,而方法体不一样,我们就可以只提取方法声明。如果一个方法只有方法声明,没有方法体,那么这个方法必须用抽象修饰。而一…

    Linux 2023年6月7日
    084
  • 当保存参数使用结构体时必备的开发技巧方式

    1、前言 想必做嵌入式产品开发都遇到过设备需要保存参数,常用的方式就是按照结构体的方式管理参数,保存时将整个结构体数据保存在 Flash 中,方便下次读取。 1.1、目的 本文时分…

    Linux 2023年6月7日
    098
  • Linux系统安装Mysql8.0流程与遇到的问题

    安装MySQL版本为:8.0.16 1、首次安装,下载命令: wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8….

    Linux 2023年6月6日
    0113
  • MySQL注入流程

    确认注入点 信息收集 数据获取 提权 写个MySQL注入流程的大纲,类似一份全局地图,能指导下一步工作。MySQL注入流程分为四步: 确认注入点 信息收集 数据获取 提权 确认注入…

    Linux 2023年6月6日
    095
  • 【小记】Ubuntu 工具链升级 gcc 流程

    我的是 Ubuntu Server 20.04 LTS,默认 gcc-9,工具链升级至 gcc-11,和 Ubuntu 22.04 LTS 保持一致。 如果本文发文时间比较旧,你所…

    Linux 2023年6月13日
    066
  • Redis的数据时如何避免丢失的?

    Redis之所以足够快,一部分的原因是它的数据都是基于内存存储的。虽然Redis更多的是作为一个旁路缓存【先在redis中查询,查询不到数据的时候,在查询持久化数据库】来使用。如果…

    Linux 2023年6月7日
    072
  • Java基础 | Stream流原理与用法总结

    Stream简化元素计算; 一、接口设计 从Java1.8开始提出了Stream流的概念,侧重对于源数据计算能力的封装,并且支持序列与并行两种操作方式;依旧先看核心接口的设计: B…

    Linux 2023年6月13日
    095
  • select,poll,epoll的区别以及使用方法

    I/O多路复用是指:通过一种机制,可以 监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。 原生socket客户端在与服务端建立连接时,…

    Linux 2023年6月14日
    087
  • Python 多线程

    import threading import time def userTest(aa,bb): print(aa) time.sleep(3) print(bb) if __n…

    Linux 2023年6月6日
    066
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球