集群与分布式

Cluster(集群) 概述

当单独一台主机无法承载现有的用户请求量;或者一台主机因为单一故障导致业务中断的时候,就可以增加服务主机数,这些主机在一起提供服务,就叫集群,而用户所看到的依然是单个的主机,用户并不用知道具体是集群内哪台设备为我提供服务,只需要知道访问集群的入口即可。

集群类型包括:

  1. LB # Load Balancing 负载均衡
  2. HA # High Availability 高可用,双机主备
  3. HP # High Performancing 高性能

构建高可扩展性系统的重要原则:在系统内部尽量避免串行化和交互

Load Balancing(负载均衡) 集群

根据请求报文的目标 IP:PORT 将其转发至后端主机集群中的某一台主机

LB 的作用:将业务请求分摊到多个后端设备进行执行,例如 Web 服务器、FTP 服务器等,当一台 web 服务器为 1W 人提供服务的时候,为了减少单台服务器的压力,可以把 1W 人分成 4 份,增加三台服务器,四台服务器每台 2500 人,共同完成工作任务,就算一台坏掉了,其余三台还能正常提供服务。也是变相实现了高可用,可以解决单点故障

类似于交换机的转发以及路由器的转发,都是把收到的请求转发到另一个地方,LB 可以称为 4 层交换或 4 层路由,工作在 4 网络 7 层模型中 4 层及以上,主要是对协议请求报文进行广播,转发,广播是对于同一个区域来进行的(LB 整个架构中的每一台设备都相当于交换机一个端口,其中一个端口(调度器)收到请求报文,广播给其余的 RS 或选择一个 RS 进行接收该请求)

负载均衡实现方式从软硬件来区分,分两种:

  1. 硬件负载均衡:通过硬件设备来实现负载均衡功能,国内常用前三家的设备
    1. F5 厂家的 BIG-IP,最好的,并发承载能力最高,价格也是最好的
    2. Citrix(思捷)厂家的 NetScaleer
    3. A10 厂家的 A10
    4. Array 厂家
    5. Redware
    6. 等等等
  2. 软件负载均衡:通过软件技术来实现负载均衡功能
    1. LVS(Linux virtual server),Linux 自带的功能 2.LB 之 LVS 概念、类型、调度方法、命令操作与实际配置.note
    2. haProxy
    3. Nginx
    4. ATS(apache traffic service)
    5. 等等。软件负载均衡基于工作的协议层次划分:
      1. 传输层:lvs,haproxy
      2. 应用层:haproxy,nginx,ats

其他

  • CoroSync 与 pacemaker

LB 的实现方式

在很久很久以前,只有一台服务器来为用户提供服务,用户直接访问这台服务器的 IP 即可,如上文描述,当一台服务器不够用的时候,想让多台服务器同时为用户提供服务,这就是负载均衡的技术,那么这么多台服务器,每个服务器都有自己的 IP,用户如何知道自己访问哪个呢?

这时候在这些服务器前面就需要有一个调度人员,来处理用户的请求,用户具体访问哪台服务器,由这个调度人员来决定,这个调度人员的工作,也可以同通过一台服务器来实现,这台调度服务器,就是实现 LB 技术的设备。而调度器(Director)的叫法,也是由此而来

High Availability(高可用) 集群

为提升系统可用性,组合多台主机构建的集群称为 High Availability(高可用,简称 HA) 集群

HA 的作用:为避免单一资源损坏导致业务终端,那么就需要增加备用资源,当主资源坏了之后,备用资源可以立刻接替已坏资源的工作继续提供服务。两个资源中间需要交换数据以确认对方是否是正常运行,是否需要把备用资源启动成主资源提供服务,这种检测机制就是 heartbeat 心跳检测。(注意:资源包括但不限于真实物理机,虚拟机,操作系统,系统中的一个应用程序,系统中的一个进程等等。比如,当一台主机宕机了,可以由另一台主机接管;当系统中的 web 进程终止了,由另一台设备的 web 进程提供服务)

HA 的实现方式

  • keepalived

Distributed(分布式) 系统概述

参考文章:

分布式系统是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统。分布式系统的出现是为了用廉价的、普通的机器完成单个计算机无法完成的计算、存储任务。其目的是利用更多的机器,处理更多的数据。

  1. 系统的各个组件分布于网络上的多个 NODE 上
  2. 各组件之间仅仅通过消息传递来通信并协调行动

分布式系统存在的意义

  1. 向上扩展的性价比越来越低
  2. 单机扩展存在性能上升临界点
  3. 处于稳定性以及可用性考虑,单机会存在多方面的问题

分布式计算:YARN

batch:MapReduce

in-memory:spark

stream:storm

分布式系统的实现

  • 负载均衡:

    • Nginx:高性能、高并发的 web 服务器;功能包括负载均衡、反向代理、静态内容缓存、访问控制;工作在应用层
    • LVS: Linux virtual server,基于集群技术和 Linux 操作系统实现一个高性能、高可用的服务器;工作在网络层
  • webserver:

    • Java:Tomcat,Apache,Jboss
    • Python:gunicorn、uwsgi、twisted、webpy、tornado
  • service:

    • SOA、微服务、spring boot,django
  • 容器:

    • docker,kubernetes
  • cache:

    • memcache、redis 等
  • 协调中心、仲裁系统:分布式协作协议,分布式系统中只要存在主备节点这种角色,则必须要有一套系统来选举出来哪个是主的,这就是仲裁系统的由来

    • zookeeper、etcd、VRRP、corosync 等
    • zookeeper 使用了 Paxos 协议 Paxos 是强一致性,高可用的去中心化分布式。zookeeper 的使用场景非常广泛,之后细讲。
  • rpc 框架:

    • grpc、dubbo、brpc
    • dubbo 是阿里开源的 Java 语言开发的高性能 RPC 框架,在阿里系的诸多架构中,都使用了 dubbo + spring boot
  • 消息队列:

    • kafka、rabbitMQ、rocketMQ、QSP
    • 消息队列的应用场景:异步处理、应用解耦、流量削锋和消息通讯
  • 实时数据平台:

    • storm、akka
  • 离线数据平台:(分布式存储)

    • hadoop(HDFS)、spark
    • PS: apark、akka、kafka 都是 scala 语言写的,看到这个语言还是很牛逼的• dbproxy:
    • cobar 也是阿里开源的,在阿里系中使用也非常广泛,是关系型数据库的 sharding + replica 代理
  • db:

    • mysql、oracle、MongoDB、HBase
  • 搜索:

    • elasticsearch、solr
  • 日志:

    • rsyslog、elk、flume

分布式系统的基本问题:可用性与一致性

分布式系统的挑战

一致性可理解为所有节点都能访问到最新版本的数据,这在单机场景下非常容易实现,使用共享内存和锁即可解决,但数据存储在单机会有两个限制:

1)单机不可用系统整体将不可用;

2)系统吞吐量受限于单机的计算能力。

消除这两个限制的方法是用多机来存储数据的多个副本,负责更新的客户端会同时更新数据的多个副本,于是问题就来了,多机之间的网络可能无法连接,当负责更新的客户端无法同时到连接多个机器时,如何能保证所有客户端都能读到最新版本的数据?

如下图 1 中所示,Client A 负责更新数据,为了保证 Server 1 和 Server 2 上的数据是一致的,Client A 会将 X=1 的写操作同时发给 Server 1 和 Server 2,但是当 Client A 和 Server 2 之间发生网络分区(网络无法连接)时,此时如果让 write X=1 的写操作在 Server 1 上成功,那 Client B 和 Client C 将从 Server 1 和 Server 2 上读取到不一致的 X 值;此时如果要保持 X 值的一致性,那么 write X=1 的写操作在 Server 1 和 Server 2 上都必须失败,这就是著名的 CAP 理论:在容忍网络分区的前提下,要么牺牲数据的一致性,要么牺牲写操作的可用性。

图 1:CAP 理论示意图

解决这个问题你可能会想到让 Client C 同时读取 Server 1 和 Server 2 上的 X 值和版本信息,然后取 Server 1 和 Server 2 最新版本的 X 值,如下图 2 所示。但 Client C 和 Server 1 之间也可能发生网络分区,这本质上是牺牲读可用性换取写可用性,并没有突破 CAP 理论。

图 2:对图 1 中可用性的优化

CAP 理论

CAP 理论由加州大学伯克利分校的计算机教授 Eric Brewer 在 2000 年提出,其核心思想是任何基于网络的数据共享系统最多只能满足数据一致性(Consistency)、可用性(Availability)和网络分区容忍(Partition Tolerance)三个特性中的两个,三个特性的定义如下:

  • Consistency(数据一致性):等同于所有节点拥有数据的最新版本
  • Availability(可用性):数据具备高可用性
  • Partition Tolerance(分区容忍):容忍网络出现分区,分区之间网络不可达

在大规模的分布式环境下,网络分区是必须容忍的现实,于是只能在可用性和一致性两者间做出选择,CAP 理论似乎给分布式系统定义了一个悲观的结局,一时间大家都按照 CAP 理论在对热门的分布式系统进行判定,譬如认为 HBase 是一个 CP 系统、Cassandra 是 AP 系统。

我个人认为这是不严谨的,理由是 CAP 理论是对分布式系统中一个数据无法同时达到可用性和一致性的断言,而一个系统中往往存在很多类型的数据,部分数据(譬如银行账户中的余额)是需要强一致性的,而另外一部分数据(譬如银行的总客户数)并不要求强一致性,所以拿 CAP 理论来划分整个系统是不严谨的, CAP 理论带来的价值是指引我们在设计分布式系统时需要区分各种数据的特点,并仔细考虑在小概率的网络分区发生时究竟为该数据选择可用性还是一致性。

对 CAP 理论的另外一种误读是系统设计时选择其一而完全不去优化另外一项,可用性和一致性的取值范围并不是只有 0 和 1,可用性的值域可以定义成 0 到 100%的连续区间,而一致性也可分为强一致性、弱一致性、读写一致性、最终一致性等多个不同的强弱等级,细想下去 CAP 理论定义的其实是在容忍网络分区的条件下,“强一致性”和“极致可用性”无法同时达到。

(注:这里用“极致可用性”而不用“100%可用性”是因为即使不考虑一致性,多台 server 组成的分布式系统也达不到 100%的可用性,如果单个 server 的可用性是 P,那 n 台 server 的极致可用性是 $1 - (1 - P)^n$,公式的意思是只要任何一台或多台 server 可用就认为系统都是可用的)

虽然无法达到同时达到强一致性和极致可用性,但我们可以根据数据类型在二者中选择其一后去优化另外一个,Paxos 协议就是一种在保证强一致性前提下把可用性优化到极限的算法。

Paxos 协议

Paxos 协议由 Leslie Lamport 最早在 1990 年提出,由于 Paxos 在云计算领域的广泛应用 Leslie Lamport 因此获得了 2013 年度图灵奖。

Paxos 协议提出只要系统中 2f+1 个节点中的 f+1 个节点可用,那么系统整体就可用并且能保证数据的强一致性,它对于可用性的提升是极大的,仍然假设单节点的可用性是 P,那么 2f+1 个节点中任意组合的 f+1 以上个节点正常的可用性 P(total)=

,又假设 P=0.99,f=2,P(total)=0.9999901494,可用性将从单节点的 2 个 9 提升到了 5 个 9,这意味着系统每年的宕机时间从 87.6 小时降到 0.086 小时,这已经可以满足地球上 99.99999999%的应用需求。

Leslie 写的两篇论文:《The Part-Time Parliament》和《Paxos Made Simple》比较完整的阐述了 Paxos 的工作流程和证明过程,Paxos 协议把每个数据写请求比喻成一次提案(proposal),每个提案都有一个独立的编号,提案会转发到提交者(Proposer)来提交,提案必须经过 2f+1 个节点中的 f+1 个节点接受才会生效,2f+1 个节点叫做这次提案的投票委员会(Quorum),投票委员会中的节点叫做 Acceptor,Paxos 协议流程还需要满足两个约束条件:

a)Acceptor 必须接受它收到的第一个提案;

b)如果一个提案的 v 值被大多数 Acceptor 接受过,那后续的所有被接受的提案中也必须包含 v 值(v 值可以理解为提案的内容,提案由一个或多个 v 和提案编号组成)。

Paxos 协议流程划分为两个阶段,第一阶段是 Proposer 学习提案最新状态的准备阶段;第二阶段是根据学习到的状态组成正确提案提交的阶段,完整的协议过程如下:

阶段 1

  1. Proposer 选择一个提案编号 n ,然后向半数以上的 Acceptors 发送编号为 n 的 prepare 请求。
  2. 如果一个 Acceptor 收到一个编号为 n 的 prepare 请求,且 n 大于它已经响应的所有 prepare 请求的编号,那么它就会保证不会再通过(accept)任何编号小于 n 的提案,同时将它已经通过的最大编号的提案(如果存在的话)作为响应。

阶段 2

  1. 如果 Proposer 收到来自半数以上的 Acceptor 对于它的 prepare 请求(编号为 n )的响应,那么它就会发送一个针对编号为 n ,value 值为 v 的提案的 accept 请求给 Acceptors,在这里 v 是收到的响应中编号最大的提案的值,如果响应中不包含提案,那么它就是任意值。

  2. 如果 Acceptor 收到一个针对编号 n 的提案的 accept 请求,只要它还未对编号大于 n 的 prepare 请求作出响应,它就可以通过这个提案。

用时序图来描述 Paxos 协议如图 3 所示:

图 3:Paxos 协议流程的时序图

上述 Paxos 协议流程看起来比较复杂,是因为要保证很多边界条件下的协议完备性,譬如初试值为空、两个 Proposer 同时提交提案等情况,但 Paxos 协议的核心可以简单描述为:Proposer 先从大多数 Acceptor 那里学习提案的最新内容,然后根据学习到的编号最大的提案内容组成新的提案提交,如果提案获得大多数 Acceptor 的投票通过就意味着提案被通过。由于学习提案和通过提案的 Acceptor 集合都超过了半数,所以一定能学到最新通过的提案值,两次提案通过的 Acceptor 集合中也一定存在一个公共的 Acceptor,在满足约束条件 b 时这个公共的 Acceptor 时保证了数据的一致性,于是 Paxos 协议又被称为多数派协议。

Paxos 协议的真正伟大之处在于它的简洁性,Paxos 协议流程中任何消息都是可以丢失的,一致性保证并不依赖某个特殊消息传递的成功,这极大的简化了分布式系统的设计,极其匹配分布式环境下网络可能分区的特点,相比较在 Paxos 协议之前的“两阶段提交(2PC)”也能保证数据强一致性,但复杂度相当高且依赖单个协调者的可用性。

那既然 Paxos 如此强大,那为什么还会出现 ZAB 协议?

ZAB 协议

Paxos 协议虽然是完备的,但要把它应用到实际的分布式系统中还有些问题要解决:

  • 在多个 Proposer 的场景下,Paxos 不保证先提交的提案先被接受,实际应用中要保证多提案被接受的先后顺序怎么办?

  • Paxos 允许多个 Proposer 提交提案,那有可能出现活锁问题,出现场景是这样的:提案 n 在第二阶段还没有完成时,新的提案 n+1 的第一阶段 prepare 请求到达 Acceptor,按协议规定 Acceptor 将响应新提案的 prepare 请求并保证不会接受小于 n+1 的任何请求,这可能导致提案 n 将不会被通过,同样在 n+1 提案未完成第二阶段时,假如提案 n 的提交者又提交了 n+2 提案,这可能导致 n+1 提案也无法通过。

  • Paxos 协议规定提案的值 v 只要被大多数 Acceptor 接受过,后续的所有提案不能修改值 v,那现实情况下我还要修改 v 值怎么办?

ZooKeeper 的核心算法 ZAB 通过一个简单的约束解决了前 2 个问题:所有提案都转发到唯一的 Leader(通过 Leader 选举算法从 Acceptor 中选出来的)来提交,由 Leader 来保证多个提案之间的先后顺序,同时也避免了多 Proposer 引发的活锁问题。

ZAB 协议的过程用时序图描述如图 4 所示,相比 Paxos 协议省略了 Prepare 阶段,因为 Leader 本身就有提案的最新状态,不需要有提案内容学习的过程,图中的 Follower 对应 Paxos 协议中的 Acceptor,Observer 对应 Paxos 中的 Learner。

图 4:ZAB 协议的工作过程

ZAB 引入 Leader 后也会带来一个新问题: Leader 宕机了怎么办?其解决方案是选举出一个新的 Leader,选举 Leader 的过程也是一个 Paxos 提案决议过程,这里不展开讨论。

那如何做到提案的值 v 可以修改呢?这不是 ZAB 协议的范畴,研究 ZooKeeper 源码后发现它是这么做的:ZooKeeper 提供了一个 znode 的概念,znode 可以被修改,ZooKeeper 对每个 znode 都记录了一个自增且连续的版本号,对 znode 的任何修改操作(create/set/setAcl)都会促发一次 Paxos 多数派投票过程,投票通过后 znode 版本号加 1,这相当于用 znode 不同版本的多次 Paxos 协议来破除单次 Paxos 协议无法修改提案值的限制。

从保证一致性的算法核心角度看 ZAB 确实是借鉴了 Paxos 的多数派思想,但它提供的全局时序保证以及 ZooKeeper 提供给用户可修改的 znode 才让 Paxos 在开源界大放异彩,所以 ZAB 的价值不仅仅是提供了 Paxos 算法的优化实现,也难怪 ZAB 的作者一直强调 ZAB 和 Paxos 是不一样的算法。

总结

CAP 理论告诉我们在分布式环境下网络分区无法避免,需要去权衡选择数据的一致性和可用性,Paxos 协议提出了一种极其简单的算法在保障数据一致性时最大限度的优化了可用性,ZooKeeper 的 ZAB 协议把 Paxos 更加简化,并提供全局时序保证,使得 Paxos 能够广泛应用到工业场景。

分布式与集群的区别是什么?

参考:原文链接

前言:

参考了一些其他文章的见解,也补充了一些自己的见解。

一、大白话解说,用生活中的例子来说明:

小饭店原来只有一个厨师,切菜洗菜备料炒菜全干。后来客人多了,厨房一个厨师忙不过来,又请了个厨师,两个厨师都能炒一样的菜,两个厨师的关系是集群

为了让厨师专心炒菜,把菜做到极致,再请了个配菜师负责切菜,备菜,备料 … , 厨师和配菜师的关系是分布式

一个配菜师也忙不过来了,又请了个配菜师,两个配菜师关系是集群

一个配菜师因故请假了,但是其余的配菜师还是该啥就干啥,只是没请假的配菜师任务均匀的加量了,但他们的任务和职责是不变的,这是集群

店里生意很好,当店长接到订单后,看哪个厨师活儿不重,就将新的订单分给谁,这就是负载均衡

集群:多个人在一起做同样的事 。

分布式 :多个人在一起做不同的事 。

负载均衡:决定将任务以某种规则分给谁做。

二、图解:

三、区别联系 (其实上面的内容应该已经让你理解 2 者了)

1)我记得在一本讲 TCP/IP 的书上有这样一句话:分布式是指多个系统协同合作完成一个特定任务的系统

分布式是解决中心化管理的问题,把所有的任务叠加到一个节点处理,太慢了。

所以,把一个大的问题拆分为多个小的问题,并分别解决,最终协同合作。分布式的主要工作是分解任务,将职能拆解。

中心化带来的主要问题是可靠性,若中心节点宕机则整个系统不可用,分布式除了解决部分中心化问题,也倾向于分散负载,但分布式会带来很多的其他问题,最主要的就是一致性

这些年吵得很热的云计算实际上只是包装在分布式之外的“新”概念。

2) 集群主要的使用场景是为了分担请求的压力,也就是在几个服务器上部署相同的应用程序,配合负载均衡来分担客户端请求。

当压力进一步增大的时候,可能在需要存储的部分,mysql 无法面对很多的写压力。因为在 mysql 做成集群之后,主要的写压力还是在 master 的机器上面,其他 slave 机器无法分担写压力,从而这个时候,也就引出来分布式。

分布式的主要应用场景是单台机器已经无法满足这种性能的要求,必须要融合多个节点,并且节点之间是相关之间有交互的。相当于在写 mysql 的时候,每个节点存储部分数据,也就是分布式存储的由来。在存储一些非结构化数据:静态文件、图片、pdf、小视频 … 这些也就是分布式文件系统的由来。

如:现在的 Spring Cloud 的分布式微服务架构,一个系统分解成了多个 Spring Boot 的微服务,各个微服务协同合作完成特定的任务。同个微服务又可以部署多台服务器形成微服务集群,从而提供高可用服务。

3)集群主要是简单加机器解决问题,对于问题本身不做任何分解

分布式处理里必然包含任务分解与答案归并。分布式中的某个子任务节点,可能由一个集群来代替;集群中任一节点,都是做一个完整的任务。

集群和分布式都是由多个节点组成,但是集群之间的通信协调基本不需要;而分布式各个节点的通信协调必不可少。

总结:


将一套系统拆分成不同子系统部署在不同服务器上(这叫分布式),然后部署多个相同的子系统在不同的服务器上(这叫集群),部署在不同服务器上的同一个子系统需要做负载均衡处理。

集群是个物理形态,分布式是个工作方式。


分布式:一个业务拆分为多个子业务,部署在多个服务器上

集群:同一个业务,部署在多个服务器上 。


分布式:不同的业务模块部署在不同的服务器上或者同一个业务模块分拆多个子业务,部署在不同的服务器上,解决高并发的问题。

集群:同一个业务部署在多台机器上,提高系统可用性。


【参考】:https://www.zhihu.com/question/20004877https://www.zhihu.com/question/20004877https://blog.csdn.net/jiangyu1013/article/details/80417961


最后修改 May 22, 2024: memory mgmt, huge pages, numa (279776de)