如何理解 CAP

本贴最后更新于 3113 天前,其中的信息可能已经斗转星移

(本文是自己初期对CAP的肤浅认识,实际上CAP理论说不可能发生的情况只有 “在分区发生的情况下,无法实现完美的一致性与可用性”,大家可以看我博文里转的一片文章, CAP理论12年回顾,以下内容有兴趣也可以喵喵,并无大致错误。)

 

 

CAP大家都知道,分别指代 Consistency,Availability,Partition tolerance。CAP therom就是说 Consistency,Availability,Partition tolerance最多同时只能满足两项,不可能三项都同时满足。
虽然定理的描述很简单,但是其过于简单了,让人觉得模棱两可,下面我按照自己对CAP的理解举例讲解一下把~

首先给个定义把:

Consistency:

一致性。一致性有不同的层次,有不同的维度。但在本文中最强的一致性,简称 强一致性 指代:只要一个partition写入了某个更新,那么其他的partition就马上能读取得到。

Availability:

可用性。可用性也有不同的层次,不同的维度。本文中,最强的可用性指代,在应用功能相同的集群的所有机器里,每台机器都提供相同的功能,且只要有一台能用,那么就能往外提供完整的服务。

Partition tolerance:

分区容忍性。就是说即使 集群内的机器 无法互相通讯,也能对外提供服务。这个条件是由上述Consistency以及Availability的实现方案中衍生出来的,直接看结论 会比较难理解为啥会出现这项...

 

下面我尝试用简单的文字来描述 为何 强一致性,强可用性 及 分区容忍性 不能同时实现把:

1、假设我们有两台机器,两台机器都可读可写(完整的可用性),我们要如何实现强一致性?

我们很容易想到,应用程序写入到一台机器的时候,写入本地,通过网络发送变更到远程的机器,提交远程,提交本地。那么我们的两台机器的集群就符合了 强一致性。

2、好了,一致性实现了,但如果一台机器A挂了,另外一台机器B也无法运转了,因为B无法将 数据同步写入到A,只能等到A恢复后才能继续工作。若抛下A不管,那么A在启动了之后,数据跟B就不一致了,没有保证强一致性,那要怎么解决呢?聪明的你肯定已经有了想法了~

 当B机器探测到A已经“确认A已经挂了”的时候,就把A没有同步的内容记到一个地方,等A重启的时候,读取B主机的更新,然后写入本机,写入完成后,再跟B一起执行强一致性的协同操作。这时候,你就有了 强一致性 以及 强可用性了,嗯,感觉棒棒的

3、但回头看一下上述解决方案中的加粗字段——“确认A已经挂了”,在实际的网络环境中,我们能确认A已经挂了么?显然,是不行的,有可能只是A与B之间的网络中断了!当A,B之间的网络中断后,如果A,B都认定这种情况就是对方死掉了,然后各自记录自己的更新,等待对方来获取的时候就会发生冲突,产生不一致的情况(脑裂)!实际上机器A,B是无法判断远在对方的TA是网络断了呢,还是TA挂了...因此结论就是...在脑裂的情况下 放弃可用性,等待两台机器互联通讯开始,才提供服务,或者 在脑裂的情况下 放弃一致性 保证可用性。

 

所以我认为CAP最多只能实现两个而不能三者兼得 可以这么理解:

1、在不考虑脑裂的情况下,我们可以实现 强可用及强一致

2、在考虑脑裂的情况下,如果我们要求 强可用 那么就必须放弃 强一致

3、在考虑脑裂的情况下,如果我们要求 强一致 那么就必须放弃 强可用

 

在实际的运用中,我们脑裂基本上是不允许发生的,如果发生了,那就是一场真正的灾难了。(在写这篇文章之后阅读了一篇新的文章,知识面得到了扩张,实际上分区的场景也是允许存在的,还有很多的系统实现,见http://www.infoq.com/cn/articles/cap-twelve-years-later-how-the-rules-have-changed)那么就只能在 可用性 及 一致性 中作文章了...好在,可用性与一致性并非一个二选一的问题——要了可用性就不能要一致性,要了一致性就不能要可用性。

在考虑脑裂的情况下,一致性与可用性的关系可以用一个形容词来比喻 此消彼长。如果你要完全的可用性,那么一致性就变成了0,如果你要完全的一致性,那么可用性就变成了0。

所以,我们考虑设计分布式系统的时候,大多数情况下就是考虑 一致性 及 可用性 平衡。

好在,前人就给我们留下了关于这个平衡的思考,如BASE理念及PAXOS算法都可以看到CAP的影子,在之后的博文里,我会继续介绍PAXOS算法以及BASE理念

 

  • 一致性
    10 引用 • 5 回帖
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    11 引用 • 5 回帖 • 614 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 25 关注
  • Windows

    Microsoft Windows 是美国微软公司研发的一套操作系统,它问世于 1985 年,起初仅仅是 Microsoft-DOS 模拟环境,后续的系统版本由于微软不断的更新升级,不但易用,也慢慢的成为家家户户人们最喜爱的操作系统。

    223 引用 • 474 回帖
  • Hibernate

    Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。

    39 引用 • 103 回帖 • 715 关注
  • 导航

    各种网址链接、内容导航。

    42 引用 • 175 回帖 • 2 关注
  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    117 引用 • 99 回帖 • 210 关注
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1436 引用 • 10056 回帖 • 492 关注
  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    200 引用 • 120 回帖 • 2 关注
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖
  • Markdown

    Markdown 是一种轻量级标记语言,用户可使用纯文本编辑器来排版文档,最终通过 Markdown 引擎将文档转换为所需格式(比如 HTML、PDF 等)。

    167 引用 • 1520 回帖
  • 创业

    你比 99% 的人都优秀么?

    82 引用 • 1395 回帖
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    692 引用 • 535 回帖 • 2 关注
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    26 引用 • 196 回帖 • 18 关注
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    59 引用 • 29 回帖 • 13 关注
  • Typecho

    Typecho 是一款博客程序,它在 GPLv2 许可证下发行,基于 PHP 构建,可以运行在各种平台上,支持多种数据库(MySQL、PostgreSQL、SQLite)。

    12 引用 • 65 回帖 • 446 关注
  • abitmean

    有点意思就行了

    29 关注
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    139 引用 • 269 回帖 • 31 关注
  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    5 引用 • 18 回帖 • 173 关注
  • uTools

    uTools 是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。

    6 引用 • 14 回帖
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 10 关注
  • IPFS

    IPFS(InterPlanetary File System,星际文件系统)是永久的、去中心化保存和共享文件的方法,这是一种内容可寻址、版本化、点对点超媒体的分布式协议。请浏览 IPFS 入门笔记了解更多细节。

    21 引用 • 245 回帖 • 242 关注
  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    407 引用 • 3574 回帖
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 98 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    209 引用 • 358 回帖
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 41 关注
  • TensorFlow

    TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。

    20 引用 • 19 回帖 • 1 关注
  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 367 关注