天天说分布式分布式,那么我们是否知道什么是分布式,分布式会遇到什么问题,有哪些理论支撑,有哪些经典的应对方案,业界是如何设计并保证分布式系统的高可用呢?
1.架构设计
这一节将从一些经典的开源系统架构设计出发,来看一下,如何设计一个高质量的分布式系统;
而一般的设计出发点,无外乎
- 冗余:简单理解为找个备胎,现任挂掉之后,备胎顶上
- 拆分:不能让一个人承担所有的重任,拆分下,每个人负担一部分,压力均摊
1.1 主备架构
给现有的服务搭建一个备用的服务,两者功能完全一致,区别在于平时只有主应用对外提供服务能力;而备应用则只需要保证与主应用能力一致,随时待机即可,并不用对外提供服务;当主应用出现故障之后,将备应用切换为主应用,原主应用下线;迅速的主备切换可以有效的缩短故障时间
基于上面的描述,主备架构特点比较清晰
- 采用冗余的方案,加一台备用服务
- 缺点就是资源浪费
其次就是这个架构模型最需要考虑的则是如何实现主备切换?
- 人工
- VIP(虚拟ip) + keepalived 机制
1.2 主从架构
主从一般又叫做读写分离,主提供读写能力,而从则只提供读能力
鉴于当下的互联网应用,绝大多数都是读多写少的场景;读更容易成为性能瓶颈,所以采用读写分离,可以有效的提高整个集群的响应能力
主从架构可以区分为:一主多从 + 一主一从再多从,以mysql的主从架构模型为例进行说明
主从模式的主要特点在于
- 添加从,源头依然是数据冗余的思想
- 读写分离:主负责读写,从只负责读,可以视为负载均衡策略
- 从需要向主同步数据,所若有的从都同步与主,对主的压力依然可能很大;所以就有了主从从的模式
关键问题则在于
- 主从延迟
- 主的写瓶颈
- 主挂之后如何选主
1.3 多主多从架构
一主多从面临单主节点的瓶颈问题,那就考虑多主多从的策略,同样是主负责提供读写,从提供读;
但是这里有一个核心点在于多主之间的数据同步,如何保证数据的一致性是这个架构模型的重点
如MySql的双主双从可以说是一个典型的应用场景,在实际使用的时候除了上面的一致性之外,还需要考虑主键id冲突的问题
1.4 普通集群模式
无主节点,集群中所有的应用职能对等,没有主次之分(当下绝大多数的业务服务都属于这种),一个请求可以被集群中任意一个服务响应;
这种也可以叫做去中心化的设计模式,如redis的集群模式,eureka注册中心,以可用性为首要目标
对于普通集群模式而言,重点需要考虑的点在于
- 资源竞争:如何确保一个资源在同一时刻只能被一个业务操作
- 如现在同时来了申请退款和货物出库的请求,如果不对这个订单进行加锁,两个请求同时响应,将会导致发货又退款了,导致财货两失
- 数据一致性:如何确保所有的实例数据都是一致的,或者最终是一致的
- 如应用服务使用jvm缓存,那么如何确保所有实例的jvm缓存一致?
- 如Eureka的分区导致不同的分区的注册信息表不一致
1.5 数据分片架构
这个分片模型的描述可能并不准确,大家看的时候重点理解一下这个思想
前面几个的架构中,采用的是数据冗余的方式,即所有的实例都有一个全量的数据,而这里的数据分片,则从数据拆分的思路来处理,将全量的数据,通过一定规则拆分到多个系统中,每个系统包含部分的数据,减小单个节点的压力,主要用于解决数据量大的场景
比如redis的集群方式,通过hash槽的方式进行分区
如es的索引分片存储
1.6 小结
这一节主要从架构设计层面对当前的分布式系统所采用的方案进行了一个简单的归类与小结,并不一定全面,欢迎各位大佬留言指正
基于冗余的思想:
- 主备
- 主从
- 多主多从
- 无中心集群
基于拆分的思想:
- 数据分片
对于拆分这一块,我们常说的分库分表也体现的是这一思想
2.理论基础
这一小节将介绍分布式系统中的经典理论,如广为流程的CAP/BASE理论,一致性理论基础paxios,raft,信息交换的Gossip协议,两阶段、三阶段等
本节主要内容参考自
- 一致性算法-Gossip协议详解 - 腾讯云开发者社区-腾讯云
- P2P 网络核心技术:Gossip 协议 - 知乎
- 从Paxos到Raft,分布式一致性算法解析_mb5fdb0a87e2fa1的技术博客_51CTO博客
- 【理论篇】浅析分布式中的 CAP、BASE、2PC、3PC、Paxos、Raft、ZAB - 知乎
2.1 CAP定理
CAP 定理指出,分布式系统 不可能 同时提供下面三个要求:
- Consistency:一致性
- 操作更新完成并返回客户端之后,所有节点数据完全一致
- Availability:可用性
- 服务一直可用
- Partition tolerance:分区容错性
- 分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务
通常来讲P很难不保证,当服务部署到多台实例上时,节点异常、网络故障属于常态,根据不同业务场景进行选择
对于服务有限的应用而言,首选AP,保证高可用,即使部分机器异常,也不会导致整个服务不可用;如绝大多数的前台应用都是这种
对于数据一致性要求高的场景,如涉及到钱的支付结算,CP可能更重要了
对于CAP的三种组合说明如下
选择 | 说明 |
---|---|
CA | 放弃分区容错性,加强一致性和可用性,其实就是传统的单机场景 |
AP | 放弃一致性(这里说的一致性是强一致性),追求分区容错性和可用性,这是很多分布式系统设计时的选择,例如很多NoSQL系统就是如此 |
CP | 放弃可用性,追求一致性和分区容错性,基本不会选择,网络问题会直接让整个系统不可用 |
2.2 BASE理论
base理论作为cap的延伸,其核心特点在于放弃强一致性,追求最终一致性
- Basically Available: 基本可用
- 指分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用
- 如大促时降级策略
- Soft State:软状态
- 允许系统存在中间状态,而该中间状态不会影响系统整体可用性
- MySql异步方式的主从同步,可能导致的主从数据不一致
- Eventual Consistency:最终一致性
- 最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态
基于上面的描述,可以看到BASE理论适用于大型高可用可扩展的分布式系统
注意其不同于ACID的强一致性模型,而是通过牺牲强一致性 来获得可用性,并允许数据在一段时间内是不一致的,但最终达到一致状态
2.3 PACELEC 定理
这个真没听说过,以下内容来自:
- 如果有一个分区('P'),分布式系统可以在可用性和一致性(即'A'和'C')之间进行权衡;
- 否则('E'),当系统在没有分区的情况下正常运行时,系统可以在延迟('L')和一致性('C')之间进行权衡。
定理(PAC)的第一部分与CAP定理相同,ELC是扩展。整个论点假设我们通过复制来保持高可用性。因此,当失败时,CAP定理占上风。但如果没有,我们仍然必须考虑复制系统的一致性和延迟之间的权衡。
2.4 Paxos共识算法
Paxos算法解决的问题是分布式共识性问题,即一个分布式系统中的各个进程如何就某个值(决议)通过共识达成一致
基于上面这个描述,可以看出它非常适用于选举;其工作流程
- 一个或多个提议进程 (Proposer) 可以发起提案 (Proposal),
- Paxos算法使所有提案中的某一个提案,在所有进程中达成一致。 系统中的多数派同时认可该提案,即达成了一致
角色划分:
- Proposer: 提出提案Proposal,包含编号 + value
- Acceptor: 参与决策,回应Proposers的提案;当一个提案,被半数以上的Acceptor接受,则该提案被批准
- 每个acceptor只能批准一个提案
- Learner: 不参与决策,获取最新的提案value
2.5 Raft算法
推荐有兴趣的小伙伴,查看
为了解决paxos的复杂性,raft算法提供了一套更易理解的算法基础,其核心流程在于:
leader接受请求,并转发给follow,当大部分follow响应之后,leader通知所有的follow提交请求、同时自己也提交请求并告诉调用方ok
角色划分:
- Leader:领导者,接受客户端请求,并向Follower同步请求,当数据同步到大多数节点上后告诉Follower提交日志
- Follow: 接受并持久化Leader同步的数据,在Leader告之日志可以提交之后,提交
- Candidate:Leader选举过程中的临时角色,向其他节点拉选票,得到多数的晋升为leader,选举完成之后不存在这个角色
2.6 ZAB协议
ZAB(Zookeeper Atomic Broadcast) 协议是为分布式协调服务ZooKeeper专门设计的一种支持崩溃恢复的一致性协议,基于该协议,ZooKeeper 实现了一种 主从模式的系统架构来保持集群中各个副本之间的数据一致性。
主要用于zk的数据一致性场景,其核心思想是Leader再接受到事务请求之后,通过给Follower,当半数以上的Follower返回ACK之后,Leader提交提案,并向Follower发送commit信息
角色划分
- Leader: 负责整个Zookeeper 集群工作机制中的核心
- 事务请求的唯一调度和处理者,保证集群事务处理的顺序性
- 集群内部各服务器的调度者
- Follower:Leader的追随者
- 处理客户端的非实物请求,转发事务请求给 Leader 服务器
- 参与事务请求 Proposal 的投票
- 参与 Leader 选举投票
- Observer:是 zookeeper 自 3.3.0 开始引入的一个角色,
- 它不参与事务请求 Proposal 的投票,
- 也不参与 Leader 选举投票
回复