分布式理论基础
2024-11-19 15:58:14 0 举报
AI智能生成
分布式理论基础是研究分布式系统、分布式算法和分布式协议的科学,其主要目标是实现高可靠性、可扩展性和容错性的分布式系统。分布式系统是由一组通过网络连接的独立计算节点组成的系统,这些节点之间可以互相通信和协作。分布式理论基础的核心内容包括分布式共识算法、分布式存储系统、分布式计算框架、分布式事务处理等。常见的分布式理论基础文件类型包括研究论文、书籍、白皮书等。这些文件通常具有很高的学术价值和技术深度,它们为人们理解和设计分布式系统提供了重要的理论支持和实践指导。
作者其他创作
大纲/内容
所谓分布式系统,就是一个业务拆分成多个子业务,分布在不同的服务器节点,共同构成的系统称为分布式系统,同一个分布式系统中的服务器节点在空间部署上是可以随意分布的,这些 服务器可能放在不同的机柜中,也可能在不同的机房中,甚至分布在不同的城市
为什么是分布式系统
集群: 多个服务器做同一个事情
分布式: 多个服务器做不同的事情
分布式和集群
分布式系统的特性
网络本身的不可靠性,因此每次网络通信都会伴随着网络不可用的风险(光纤、路由、DNS等硬件 设备或系统的不可用),都会导致最终分布式系统无法顺利进行一次网络通信,另外,即使分布式 系统各节点之间的网络通信能够正常执行,其延时也会大于单机操作,存在巨大的延时差别,也会影响消息的收发过程,因此消息丢失和消息延迟变的非常普遍。
通讯异常
网络之间出现了网络不连通,但各个子网络的内部网络是正常的,从而导致整个系统的网络环境被 切分成了若干个孤立的区域,分布式系统就会出现局部小集群,在极端情况下,这些小集群会独立 完成原本需要整个分布式系统才能完成的功能,包括数据的事务处理,这就对分布式一致性提出非常大的挑战。
网络分区
节点故障
分布式系统每一次请求与响应存在特有的“三态”概念,即成功、失败和超时
三态:成功/失败/超时
分布式系统在发生调用的时候可能会出现 失败 超时的情况. 这个时候需要重新发起调用.
重发
任意多次执行对资源本身所产生的影响均与一次执行的影响相同
幂等
分布式系统面临的问题
基础介绍
写入什么,立马读到什么
强一致性
不承诺立即读到写入的值,尽可能保证某个时间级别达到一致。
弱一致性
最终一致性也是弱一致性的一种,它无法保证数据更新后,所有后续的访问都能看到最新数值,而是需要一个时间,在这个时间之后可以保证这一点(就是在一段时间后,节点间的数据会最终达到 一致状态),而在这个时间内,数据也许是不一致的,这个系统无法保证强一致性的时间片段被称 为「不一致窗口」。不一致窗口的时间长短取决于很多因素,比如备份数据的个数、网络传输延迟 速度、系统负载等。
最终一致性
如果进程A通知进程B它已更新了一个数据项,那么进程B的后续访问将返回更新后的值。与进程A无因果关系的进程C的访问遵守一般的最终一致性规则
因果一致性
当进程A自己更新一个数据项之后,它总是访问到更新过的值,绝不会看到旧值。这是因果一致性模型的一个特例
读己所写一致性
它把访问存储系统的进程放到会话的上下文中。只要会话还存在,系统就保证“读己之所写”一致性。如果由于某些失败情形令会话终止,就要建立新的会话,而且系统的保证不会延续到新的会话。
会话一致性
如果一个进程已经读取到一个特定值,那么该进程不会读取到该值以前的任何值。
单调读一致性
单调写一致性(串行)
一致性分类
数据一致性
一旦客户端将值写入任何一台服务器并获得响应,那么之后client从其他任何服务器 读取的都是刚写入的数据
一致性(强一致性) Consistency
系统中非故障节点收到的每个请求都必须有响应,在可用系统中,如果我们的客户端向服务器 发送请求,并且服务器未崩溃,则服务器必须最终响应客户端,不允许服务器忽略客户的请求
可用性 Availability
允许网络丢失从一个节点发送到另一个节点的任意多条消息,即不同步. 也就是说,G1和G2发送给 对方的任何消息都是可以放弃的,也就是说G1和G2可能因为各种意外情况,导致无法成功进行同 步,分布式系统要能容忍这种情况。
什么是分区?
分区容错性 Partition tolerance
分布式系统中,必须满足 CAP 中的 P,此时只能在 C/A 之间作出取舍。若要保证一致性:则必须进行节点间数据同步,同步期间数据锁定,导致期间的读取失败或超时,破坏了可用性;若要保证可用性:则不允许节点间同步期间锁定,这又破坏了一致性。
CAP为什么不能同时满足?
舍弃P(选择C/A):单点的传统关系型数据库 DBMS(MySQL/Oracle),但如果采用集群就必须考虑P了;舍弃A(选择C/P):是分布式系统要保证P,而且保证一致性,如 ZooKeeper / Redis / MongoDB / HBase;舍弃C(选择A/P):是分布式系统要保证P,而且保证可用性,如 CoachDB / Cassandra / DynamoDB。
保证可用性和分区容错,舍弃强一致性,但保证最终一致性,比如一些高并发的站点(秒杀、淘宝、12306)。最终近似于兼顾了三个特性。
AC如何权衡?
CAP
基本可用(Basically Available)
柔性状态(Soft State)
最终一致性(Eventual Consisstency)
BASE
分布式理论
分布式事务的场景
事务 ACID
协调者向所有参与者发送事务内容,询问是否可以提交事务,并等待答复各参与者执行事务操作,将 undo和 redo 信息记入事务日志中(但不提交事务)如参与者执行成功,给协调者反馈同意,否则反馈中止
第一阶段(voting phase投票阶段)
协调者节点向所有参与者节点发出正式提交(`commit`)的请求。参与者节点正式完成操作,并释放在整个事务期间内占用的资源。参与者节点向协调者节点发送ack完成消息。协调者节点收到所有参与者节点反馈的ack完成消息后,完成事务。
提交(commit)
协调者节点向所有参与者节点发出回滚操作(`rollback)的请求。参与者节点利用阶段1写入的undo信息执行回滚,并释放在整个事务期间内占用的资源。参与者节点向协调者节点发送ack回滚完成消息。协调者节点受到所有参与者节点反馈的ack回滚完成消息后,取消事务。
回滚(rollback)
子主题
第二阶段(commit phase提交执行阶段)
流程
尽量保证了数据的强一致,适合对数据强一致要求很高的关键领域。(其实也不能100%保证强一致)
优点
性能问题:执行过程中,所有参与节点都是事务阻塞型的。当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态。
可靠性问题:参与者发生故障。协调者需要给每个参与者额外指定超时机制,超时后整个事务失败。协调者发生故障。参与者会一直阻塞下去。需要额外的备机进行容错。
数据一致性问题:二阶段无法解决的问题:协调者在发出`commit`消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交。
太过保守:在进行事务提交询问的过程中,参与者出现故障而导致协调者始终无法获取到所有参与者的响应信息的话,此时协调者只能依靠自身的超时机制来判断是否需要中断事务,这样的策略过于 保守,即没有完善的容错机制,任意一个结点的失败都会导致整个事务的失败。
缺点
两阶段提交(2PC)
事务询问 协调者向所有参与者发出包含事务内容的 `canCommit` 请求,询问是否可以提交事务,并等待所有参与者答复。
响应反馈 参与者收到 `canCommit` 请求后,如果认为可以执行事务操作,则反馈 yes 并进入预备状态,否则反馈 no。
阶段一:CanCommit阶段
发送预提交请求 :协调者向参与者发送`PreCommit`请求,并进入准备阶段事务预提交 :参与者接收到`PreCommit`请求后,会执行事务操作,并将`undo`和`redo`信息记录到事务日志中(但不提交事务)响应反馈 :如果参与者成功的执行了事务操作,则返回ACK响应,同时开始等待最终指令。
所有参与者均反馈 yes,协调者预执行事务。
发送中断请求 :协调者向所有参与者发送`abort`请求。中断事务 :参与者收到来自协调者的`abort`请求之后(或超时之后,仍未收到协调者的请求),执行事务的中断。
任何一个参与者向协调者发送了No响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断
阶段二:PreCommit阶段
发送提交请求 协调接收到参与者发送的ACK响应,那么他将从预提交状态进入到提交状态。并向所有参与者发送`doCommit`请求。事务提交 参与者接收到`doCommit`请求之后,执行正式的事务提交。并在完成事务提交之后释放所有事务资源。响应反馈 事务提交完之后,向协调者发送ack响应。完成事务 协调者接收到所有参与者的ack响应之后,完成事务。
执行提交
1. 发送中断请求 如果协调者处于工作状态,向所有参与者发出 abort 请求2. 事务回滚 参与者接收到abort请求之后,利用其在阶段二记录的`undo`信息来执行事务的回滚操作,并在完成回滚之后释放所有的事务资源。3. 反馈结果 参与者完成事务回滚之后,向协调者反馈ACK消息4. 中断事务 协调者接收到参与者反馈的ACK消息之后,执行事务的中断。
中断事物
阶段三:doCommit阶段
3PC对比2PC提升点
相比二阶段提交,三阶段提交降低了阻塞范围,在等待超时后协调者或参与者会中断事务。避免了协调者单点问题,阶段 3 中协调者出现问题时,参与者会继续提交事务
数据不一致问题依然存在,当在参与者收到 `preCommit` 请求后等待 `doCommit` 指令时,此时如果协调者请求中断事务,而协调者无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致。
3PC和2PC对比
三阶段提交(3PC)
TCC方案是一种应用层面侵入业务的两阶段提交(TCC 事务机制相对于传统事务机制(X/Open XA))。是目前最火的一种柔性事务方案,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作
主要是对业务系统做检测及资源预留 (加锁,锁住资源)
第一阶段 : Try(尝试)
Confirm(确认):执行真正的业务执行业务,释放锁Cancle(取消):是预留资源的取消出问题,释放锁
第二阶段: Confirm(确认)/ Cancel(取消)
性能提升:具体业务来实现控制资源锁的粒度变小,不会锁定整个资源
数据最终一致性:基于 Confirm 和 Cancel 的幂等性,保证事务最终完成确认或者取消,保证数据的一致性
可靠性:解决了 XA 协议的协调者单点故障问题,由主业务方发起并控制整个业务活动,业务活动管理器也变成多点,引入集群
CC 的 Try、Confirm 和 Cancel 操作功能要按具体业务来实现,业务耦合度较高,提高了开发成本
优缺点:
事务补偿TCC
NWR是一种在分布式存储系统中用于控制一致性级别的一种策略。在亚马逊的云存储系统中,就应用 NWR来控制一致性。
N(node):在分布式存储系统中,有多少份备份数据 W:代表一次成功的更新操作要求至少有w份数据写入成功 R: 代表一次成功的读数据操作要求至少有R份数据成功读取
简介
原理
NWR协议
Gossip 协议也叫 Epidemic 协议 (流行病协议)。原本用于分布式数据库中节点同步数据使用, 后被广泛用于数据库复制、信息扩散、集群成员身份确认、故障探测等gossip 协议利用一种随机的方式将信息传播到整 个网络中,并在一定时间内使得系统内的所有节点数据一致。Gossip 其实是一种去中心化思路的分布式协议,数据通过节点像病毒一样逐个传播。因为是指数级传播,整体传播速度非常快,解决状态在集群中的传播和状态一致性的保证两个问题。
是以固定的概率传播所有的数据。所有参与节点只有两种状态:Suspective(病原)、 Infective(感染)。过程是种子节点会把所有的数据都跟其他节点共享,以便消除节点之间数据的任 何不一致,它可以保证最终、完全的一致。缺点是消息数量非常庞大,且无限制;通常只用于新加入节点的数据初始化
反熵传播
是以固定的概率仅传播新到达的数据。所有参与节点有三种状态:Suspective(病原)、 Infective(感染)、Removed(愈除)。过程是消息只包含最新 update,谣言消息在某个时间点之后会 被标记为 removed,并且不再被传播。缺点是系统有一定的概率会不一致,通常用于节点间数据 增量同步。
谣言传播
传播方式
扩展性:允许节点的任意增加和减少,新增节点的状态 最终会与其他节点一致 容错:任意节点的宕机和重启都不会影响 Gossip 消息的传播,具有天然的分布式系统容错特性 去中心化:无需中心节点,所有节点都是对等的,任意节点无需知道整个网络状况,只要网络 连通,任意节点可把消息散播到全网最终一致性:Gossip 协议实现信息指数级的快速传播,因此在有新信息需要传播时,消息可 以快速地发送到全局节点,在有限的时间内能够做到所有节点都拥有最新的数据。
消息延迟:节点随机向少数几个节点发送消息,消息最终是通过多个轮次的散播而到达全网; 不可避免的造成消息延迟。 消息冗余:节点定期随机选择周围节点发送消息,而收到消息的节点也会重复该步骤;不可避 免的引起同一节点消息多次接收,增加消息处理压力
优缺点
Gossip 协议由于以上的优缺点,所以适合于 AP 场景的数据一致性处理,常见应用有:P2P 网络通信、 Redis Cluster、Consul
Gossip协议
Paxos算法是基于消息传递且具有高度容错特性的一致性算法
在常见的分布式系统中,总会发生诸如机器宕机或网络异常(包括消息的延迟、丢失、重复、乱序,还有网络分区)等情况。Paxos算法需要解决的问题就是如何在一个可能发生上述异常的分布式系 统中,快速且正确地在集群内部对某个数据的值达成一致,并且保证不论发生以上任何异常,都不会破坏整个系统的一致性。
引入多个协调者,在选择出主协调者
2PC 和 3PC的时候在一定程度上是可以解决数据一致性问题的,但是并没有完全解决就是协调者宕机的情况,如何解决2PC和3PC的存在的问题呢 ?
Paxos解决了什么问题?
决策模型
无故障的Basic Paxos
多数派中的一个Acceptor发生故障,因此多数派大小变为2。在这种情况下,Basic Paxos协议仍然成功
Acceptor失败时的basic Paxos
Proposer失败时的basic Paxos
当多个提议者发生冲突时的basic Paxos
Base Paxos
在 Base Paxos 基础上选择主决策者
Multi Paxos
Multi-Paxos在实施的时候会将Proposer,Acceptor和Learner的角色合并统称为“服务器”。因此, 最后只有“客户端”和“服务器”
Multi Paxos 角色重叠
Paxos协议
Leader(主节点):接受 client 更新请求,写入本地后,然后同步到其他副本中 Follower(从节点):从 Leader 中接受更新请求,然后写入本地日志文件。对客户端提供读 请求Candidate(候选节点):如果 follower 在一段时间内未收到 leader 心跳。则判断 leader 可能故障,发起选主提议。节点状态从 Follower 变为 Candidate 状态,直到选主结束
节点状态
termId:任期号,时间被划分成一个个任期,每次选举后都会产生一个新的 termId,一个任期内只有一个 leader
RequestVote:请求投票,candidate 在选举过程中发起,收到多数派响应后,成为 leader
相关概念
竞选阶段流程
gif动画
Leader节点宕机
如果有多个 Follower 成为 Candidate,并且所获得票数相同,那么就需要重新开始投票,例如下 图中 Candidate B 和 Candidate D 都获得两票,因此需要重新开始投票。
当重新开始投票时,由于每个节点设置的随机竞选超时时间不同,因此能下一次再次出现多个 Candidate 并获得同样票数的概率很低
多个 Candidate 竞选
数据的同步
网络分区情况日志复制
Raft流程动画:
Raft 流程动画:
Raft协议
Lease机制,翻译过来即是租约机制,是一种在分布式系统常用的协议,是维护分布式系统数据一致性 的一种常用工具
Lease是颁发者对一段时间内数据一致性的承诺; 颁发者发出Lease后,不管是否被接收,只要Lease不过期,颁发者都会按照协议遵守承诺; Lease的持有者只能在Lease的有效期内使用承诺,一旦Lease超时,持有者需要放弃执行,重新申请Lease。
特点
设计能容忍双主的分布式协议 Raft协议-通过Term版本高的同步低的用lease机制 涉及去中心化-Gossip协议
主要解决思路
某个时刻主节点突然出现网络抖动或者网络中断情况(注意:不是宕机),导致从节点无法接受到心跳,又竞选出新的主节点,出现的双主问题。
双主问题?
引入中心节点负责下发Lease
出现网络问题
如果网络恢复
如果主节点宕机,其他节点申请Lease也会失败,承认主节点存在
Lease 原理
lease的容错
Lease机制
分布式一致性协议
Server端每间隔 t 秒向Node集群发起监测请求,设定超时时间,如果超过超时时间,则判断“死亡”
周期性检测
在周期检测心跳机制的基础上,统计一定周期内节点的返回情况(包括超时及正确返回),以此计 算节点的“死亡”概率。另外,对于宣告“濒临死亡”的节点可以发起有限次数的重试,以作进一步判 断。如果超过次数则可以把该节点踢出集群
累计失效检测
心跳检测
高可用(High Availability)是系统架构设计中必须考虑的因素之一,通常是指,经过设计来减少系统不能提供服务的时间
主备模式就是Active-Standby模式,当主机宕机时,备机接管主机的一切工作,待主机恢复正常 后,按使用者的设定以自动(热备)或手动(冷备)方式将服务切换到主机上运行。在数据库部分,习惯称之为MS模式。MS模式即Master/Slave模式,这在数据库高可用性方案中比较常用,如 MySQL、Redis等就采用MS模式实现主从复制。保证高可用
主从(主备)模式 【MS模式】
互备模式指两台主机同时运行各自的服务工作且相互监测情况。在数据库高可用部分,常见的互备是MM模式。MM模式即Multi-Master模式,指一个系统存在多个master,每个master都具有 read-write能力,会根据时间戳或业务逻辑合并版本。
双主互备(故障转移) 【MM模式】
集群模式是指有多个节点在运行,同时可以通过主控节点分担服务请求。集群模式需要解决主控节点本身的高可用问题,一般采用主备模式, 例如Redis
集群模式
高可用HA设计
在高可用(HA)系统中,当联系两个节点的\"心跳线\"断开时(即两个节点断开联系时),本来为 一个整体、动作协调的HA系统,就分裂成为两个独立的节点(即两个独立的个体)。由于相互失去了 联系,都以为是对方出了故障,两个节点上的HA软件像\"裂脑人\"一样,\"本能\"地争抢\"共享资源\"、 争起\"应用服务\"。就会发生严重后果:共享资源被瓜分、两边\"服务\"都起不来了;两边\"服务\"都起来了,但同时读写\"共享存储\",导致数据损坏(常见如数据库轮询着的联机日志出错)。
高可用服务器各节点之间心跳线链路发生故障,导致无法正常通信。
因网卡及相关驱动坏了,ip配置及冲突问题(网卡直连)。
因心跳线间连接的设备故障(网卡及交换机)。
因仲裁的机器出问题(采用仲裁的方案)。
高可用服务器上开启了iptables防火墙阻挡了心跳消息传输。
高可用服务器上心跳网卡地址等信息配置不正确,导致发送心跳失败。
其他服务配置不当等原因,如心跳方式不同,心跳广插冲突、软件Bug等。
脑裂出现的原因(总的来说就是节点之间无法进行正常的通讯)
高可用HA下的脑裂问题
高可用
容错的处理是保障分布式环境下相应系统的高可用或者健壮性,一个典型的案例就是对于缓存穿透问题的解决方案
容错性
负载均衡器有硬件解决方案,也有软件解决方案。硬件解决方案有著名的F5,软件有`LVS、HAProxy、 Nginx`等。 以Nginx为例,负载均衡策略:
负载均衡
分布式系统主要关心问题
HttpURLConnection
Apache Common HttpClient
Okhttp3
restTemplate
Http应用协议
Java RMI
Hessian
Dubbo
gRPC
RPC
分布式架构的服务调用
分布式协调技术主要用来解决分布式环境当中多个进程之间的同步控制,让他们有序的去访问某种临界资源,防止造成\"脏数据\"的后果。
Redis
zk
分布式锁
服务协调
消息队列中间件主要解决应用耦合,异步消息,流量削锋等问题
消息队列(MQ)
通过在不同的层次尽可能地过滤掉无效请求。(比如说重复请求)
通过CDN过滤掉大量的图片,静态资源的请求
再通过类似Redis这样的分布式缓存过滤请求
分层过滤的核心思想
对写数据进行基于时间的合理分片,过滤掉过期的失效请求。
对写请求做限流保护,将超出系统承载能力的请求过滤掉。
涉及到的读数据不做强一致性校验,减少因为一致性校验产生瓶颈的问题。
对写数据进行强一致性校验,只保留最后有效的数据。
分层过滤的基本原则
流量削峰漏斗:层层削峰
服务削峰
整个架构整体的负载超出了预设的上限阈值或即将到来的流量预计将会超过预设的阈值时,为了保证重要或基本的服务能正常运行,我们可以将一些 不重要 或 不紧急 的服务或任务进行服务的延迟使用 或 暂停使用
什么是?
页面降级 —— 可视化界面禁用点击按钮、调整静态页面
延迟服务 —— 如定时任务延迟处理、消息入MQ后延迟处理
写降级 —— 直接禁止相关写操作的服务请求
读降级 —— 直接禁止相关读的服务请求
缓存降级 —— 使用缓存方式来降级部分读频繁的服务接口
从分布式,微服务架构全局的 视角来看,降级处理方案
抛异常
返回NULL
调用Mock数据
调用Fallback处理逻辑
针对后端代码层面的降级处理策略
降级策略
结合服务能否降级的优先原则,并根据台风预警(都属于风暴预警)的等级进行参考设计,可将分布 式服务架构的所有服务进行故障风暴等级划分为以下四种
分级降级
服务降级
限流的目的是通过对并发访问请求进行限速或者一个时间窗口内的的请求数量进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队或等待
多维度限流
计数器(固定窗口)
计数器(滑动窗口)
通过一个固定大小FIFO队列+定时取队列元素的方式实现,请求进入队列后会被匀速的取出处理(桶底部开口匀速出水),当队列被占满后后来的请求会直接拒绝(水倒的太快从桶中溢出来)
优点:可以削峰填谷,不论请求多大多快,都只会匀速发给后端,不会出现突刺现象,保证下游服务正常运行缺点:在桶队列中的请求会排队,响应时间拉长
漏桶
令牌桶
限流算法
服务限流
牺牲局部,保全整体的措施就叫做熔断,避免因为个别故障产生连锁故障,造成雪崩。
Hystrix
通过并发线程数进行限制 通过响应时间对资源进行降级 系统负载保护
Sentinel
机制实现
服务熔断
故障快速定位
各个调用环节的性能分析
调用链绑定业务后查看具体每条业务数据对应的链路问题,可以得到用户的行为路径,经过了哪些 服务器上的哪个服务,汇总分析应用在很多业务场景
数据分析
通过可视化分布式系统的模块和他们之间的相互联系来理解系统拓扑。点击某个节点会展示这个 模块的详情,比如它当前的状态和请求数量。
生成服务调用拓扑图
链路跟踪具备的功能
低侵入性,应用透明
低损耗
大范围部署,扩展性
设计目标
埋点即系统在当前节点的上下文信息,可以分为客户端埋点、服务端埋点,以及客户端和服务 端双向型埋点。埋点日志通常要包含以下内容:TraceId、RPCId、调用的开始时间,调用类型,协议类型,调用方ip和端口,请求的服务名等 信息;调用耗时,调用结果,异常信息,消息报文等
埋点和生成日志
日志的采集和存储有许多开源的工具可以选择,一般来说,会使用离线+实时的方式去存储日志,主要是分布式日志采集的方式。典型的解决方案如Flume结合Kafka
抓取和存储日志
一条调用链的日志散落在调用经过的各个服务器上,首先需要按 TraceId 汇总日志,然后按照 RpcId 对调用链进行顺序整理。调用链数据不要求百分之百准确,可以允许中间的部分日志丢失
分析和统计调用链数据
汇总得到各个应用节点的调用链日志后,可以针对性的对各个业务线进行分析。需要对具体日志 进行整理,进一步储存在HBase或者关系型数据库中,可以进行可视化的查询
计算和展示
链路跟踪设计原则
链路跟踪Trace模型
服务链路追踪
分布式服务治理
分布式理论基础
0 条评论
下一页