大家好我是咸鱼了大半年的一灰灰,终于放暑假了,把小孩送回老家,作为咸鱼的我也能够翻翻身了,接下来将趁着寒假的这段时间,将筹备一个全新的分布式专栏,为了给大家提供更好的浏览体验,能够再我的集体站点上查看系列的专栏内容:
https://hhui.top/ 分布式
天天说分布式分布式,那么咱们是否晓得什么是分布式,分布式会遇到什么问题,有哪些实践撑持,有哪些经典的应答计划,业界是如何设计并保障分布式系统的高可用呢?
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 定理
这个真没听说过,以下内容来自:
- Distributed System Design Patterns | by Nishant | Medium
- 如果有一个分区(’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 算法
举荐有趣味的小伙伴,查看
- Raft 算法动画演示
- 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 实现了一种 主从模式的零碎架构来放弃集群中各个正本之间的数据一致性。
- zookeeper 外围之 ZAB 协定就这么简略!
次要用于 zk 的数据一致性场景,其核心思想是 Leader 再承受到事务申请之后,通过给 Follower,当半数以上的 Follower 返回 ACK 之后,Leader 提交提案,并向 Follower 发送 commit 信息
角色划分
-
Leader: 负责整个 Zookeeper 集群工作机制中的外围
- 事务申请的惟一调度和解决者,保障集群事务处理的程序性
- 集群外部各服务器的调度者
-
Follower:Leader 的追随者
- 解决客户端的非实物申请,转发事务申请给 Leader 服务器
- 参加事务申请 Proposal 的投票
- 参加 Leader 选举投票
-
Observer:是 zookeeper 自 3.3.0 开始引入的一个角色,
- 它不参加事务申请 Proposal 的投票,
- 也不参加 Leader 选举投票
- 只提供非事务的服务(查问),通常在不影响集群事务处理能力的前提下晋升集群的非事务处理能力。
2.7 2PC 协定
two-phase commit protocol,两阶段提交协定,次要是为了解决强一致性,中心化的强一致性协定
角色划分
- 协调节点(coordinator):中心化
- 参与者节点(partcipant):多个
执行流程
协调节点接管申请,而后向参与者节点提交 precommit
,当所有的参与者都回复 ok 之后,协调节点再给所有的参与者节点提交commit
,所有的都返回 ok 之后,才表明这个数据确认提交
当第一个阶段,有一个参与者失败,则所有的参与者节点都回滚
特点
长处在于实现简略
毛病也很显著
- 协调节点的单点故障
- 第一阶段全副 ack 失常,第二阶段存在局部参与者节点异样时,可能呈现不统一问题
2.8 3PC 协定
分布式事务:两阶段提交与三阶段提交 – SegmentFault 思否
在两阶段的根底上进行扩大,将第一阶段划分两部,cancommit + precommit,第三阶段则为 docommit
第一阶段 cancommit
该阶段协调者会去询问各个参与者是否可能失常执行事务,参与者依据本身状况回复一个预估值,绝对于真正的执行事务,这个过程是轻量的
第二阶段 precommit
本阶段协调者会依据第一阶段的询盘后果采取相应操作,若所有参与者都返回 ok,则协调者向参与者提交事务执行 (单不提交) 告诉;否则告诉参与者 abort 回滚
第三阶段 docommit
如果第二阶段事务未中断,那么本阶段协调者将会根据事务执行返回的后果来决定提交或回滚事务,若所有参与者失常执行,则提交;否则协调者 + 参与者回滚
在本阶段如果因为协调者或网络问题,导致参与者迟迟不能收到来自协调者的 commit 或 rollback 申请,那么参与者将不会如两阶段提交中那样陷入阻塞,而是期待超时后持续 commit,绝对于两阶段提交尽管升高了同步阻塞,但依然无奈完全避免数据的不统一
特点
-
升高了阻塞与单点故障:
- 参与者返回 CanCommit 申请的响应后,期待第二阶段指令,若期待超时 / 协调者宕机,则主动 abort,升高了阻塞;
- 参与者返回 PreCommit 申请的响应后,期待第三阶段指令,若期待超时 / 协调者宕机,则主动 commit 事务,也升高了阻塞;
-
数据不统一问题仍然存在
- 比方第三阶段协调者收回了 abort 申请,而后有些参与者没有收到 abort,那么就会主动 commit,造成数据不统一
2.9 Gossip 协定
Gossip 协定,顾名思义,就像风言风语一样,利用一种随机、带有传染性的形式,将信息流传到整个网络中,并在肯定工夫内,使得零碎内的所有节点数据统一。Gossip 协定通过下面的个性,能够保证系统能在极其状况下(比方集群中只有一个节点在运行)也能运行
- P2P 网络核心技术:Gossip 协定 – 知乎
次要用在分布式数据库系统中各个正本节点同步数据之用,这种场景的一个最大特点就是组成的网络的节点都是对等节点,是非结构化网络
工作流程
- 周期性的流传音讯,通常周期时间为 1s
- 被感化的节点,随机抉择 n 个相邻节点,流传音讯
- 每次流传音讯都抉择还没有发送过的节点进行流传
- 收单音讯的节点,不会流传给向它发送音讯的节点
特点
- 扩展性:容许节点动静减少、缩小,新增的节点状态最终会与其余节点统一
- 容错:网络中任意一个节点宕机重启都不会影响音讯流传
- 去中心化:不要求核心节点,所有节点对等,任何一个节点无需晓得整个网络情况,只有网络连通,则一个节点的音讯最终会散播到整个网络
- 一致性收敛:协定中的音讯会以一传十、十传百一样的指数级速度在网络中疾速流传,因而零碎状态的不统一能够在很快的工夫内收敛到统一。音讯传播速度达到了 logN
- 简略:Gossip 协定的过程极其简略,实现起来简直没有太多复杂性
毛病
- 音讯提早:节点只会随机向少数几个节点发送音讯,音讯最终是通过多个轮次的散播而达到全网的,因而应用 Gossip 协定会造成不可避免的音讯提早
- 音讯冗余:节点会定期随机抉择四周节点发送音讯,而收到音讯的节点也会反复该步骤,导致音讯的冗余
2.10 一灰灰的小结
本节次要介绍的是分布式系统设计中的一些常见的实践基石,如分布式中如何保障一致性,如何对一个提案达成共识
- BASE,CAP,PACELEC 实践:构建稳固的分布式系统应该思考的方向
- paxos,raft 共识算法
- zab 一致性协定
- gossip 音讯同步协定
3. 算法
这一节将次要介绍下分布式系统中的经典的算法,比方罕用于分区的一致性 hash 算法,实用于一致性的 Quorum NWR 算法,PBFT 拜占庭容错算法,区块链中大量应用的工作量证实 PoW 算法等
3.1 一致性 hash 算法
一致性 hash 算法,次要利用于数据分片场景下,无效升高服务的新增、删除对数据复制的影响
通过对数据项的键进行哈希解决映射其在环上的地位,而后顺时针遍历环以查找地位大于该项地位的第一个节点,将每个由键标识的数据调配给 hash 环中的一个节点
统一散列的次要长处是增量稳定性; 节点增加删除,对整个集群而言,仅影响其间接街坊,其余节点不受影响。
留神:
- redis 集群实现了一套 hash 槽机制,其核心思想与一致性 hash 比拟类似
3.2 Quorum NWR 算法
用来保证数据冗余和最终一致性的投票算法,其次要数学思维来源于鸽巢原理
- 分布式系统之 Quorum(NRW)算法 - 阿里云开发者社区
- N 示意正本数,又叫做复制因子(Replication Factor)。也就是说,N 示意集群中同一份数据有多少个正本
- W,又称写一致性级别(Write Consistency Level),示意胜利实现 W 个正本更新写入,才会视为本次写操作胜利
- R 又称读一致性级别(Read Consistency Level),示意读取一个数据对象时须要读 R 个正本, 才会视为本次读操作胜利
Quorum NWR 算法要求每个数据拷贝对象 都能够投 1 票,而每一个操作的执行则须要获取最小的读票数,写票数;通常来讲写票数 W 个别须要超过 N /2,即咱们通常说的失去半数以上的票才示意数据写入胜利
事实上当 W =N、R= 1 时,即所谓的 WARO(Write All Read One)。就是 CAP 实践中 CP 模型的场景
3.3 PBFT 拜占庭算法
拜占庭算法次要针对的是分布式场景下无响应,或者响应不可信的状况下的容错问题,其外围分三段流程,如下
假如集群节点数为 N,f 个故障节点 (无响应) 和 f 个问题节点(无响应或谬误响应),f+ 1 个失常节点,即 3f+1=n
- 客户端向主节点发动申请,主节点承受申请之后,向其余节点播送 pre-prepare 音讯
- 节点承受 pre-prepare 音讯之后,若批准申请,则向其余节点播送 prepare 音讯;
- 当一个节点承受到 2f+ 1 个 prepare 新音讯,则进入 commit 阶段,并播送 commit 音讯
- 当收到 2f+1 个 commit 音讯后(包含本人),代表大多数节点曾经进入 commit 阶段,这一阶段曾经达成共识,于是节点就会执行申请,写入数据
相比 Raft 算法齐全不适应有人作恶的场景,PBFT 算法能容忍 (n 1)/3 个歹意节点 (也能够是故障节点)。另外,相比 PoW 算法,PBFT 的长处是不耗费算 力。PBFT 算法是 O(n ^ 2) 的音讯复杂度的算法,所以以及随着音讯数 的减少,网络时延对系统运行的影响也会越大,这些都限度了运行 PBFT 算法的分布式系统 的规模,也决定了 PBFT 算法实用于中小型分布式系统
3.4 PoW 算法
工作量证实 (Proof Of Work,简称 PoW),同样利用于分布式下的一致性场景,区别于后面的 raft, pbft, paxos 采纳投票机制达成共识计划,pow 采纳工作量证实
客户端须要做肯定难度的工作能力得出一个后果,验证方却很容易通过后果来查看出客户端是不是做了相应的工作,通过耗费肯定工作浪,减少音讯伪造的老本,PoW 以区块链中广泛应用而广为人知,上面以区块链来简略说一下 PoW 的算法利用场景
以 BTC 的转账为例,A 转 n 个 btc 给 B,如何保障不会同时将这 n 个币转给 C?
- A 转账给 B,交易信息记录在一个区块 1 中
- A 转账给 C,交易信息被记录在另一个区块 2 中
- 当区块 1 被矿工胜利提交到链上,并被大多数认可(通过校验区块链上的 hash 值验证是否精确,而这个 hash 值体现的是矿工的工作量),此时尚未提交的区块 2 则会被摈弃
- 若区块 1 被提交,区块 2 也被提交,各自有局部人认可,就会导致分叉,区块链中采纳的是优选最长的链作为主链,抛弃分叉的局部(这就属于区块链的知识点了,有趣味的小伙伴能够扩大下相干知识点,这里就不开展了)
PoW 的算法,次要利用在下面的区块提交验证,通过 hash 值计算来耗费算力,以此证实矿工的确有付出,失去少数认可的能够达成共识
3.5 一灰灰的小结
本节次要介绍了下以后分布式下常见的算法,
- 分区的一致性 hash 算法: 基于 hash 环,缩小节点动静减少缩小对整个集群的影响;实用于数据分片的场景
- 实用于一致性的 Quorum NWR 算法: 投票算法,定义如何就一个提案达成共识
- PBFT 拜占庭容错算法: 实用于集群中节点故障、或者不可信的场景
- 区块链中大量应用的工作量证实 PoW 算法: 通过工作量证实,认可节点的提交
4. 技术思维
这一节的内容绝对后面几个而言,并不太容易进行清晰的分类;次要蕴含一些高质量的分布式系统的实际中,值得举荐的设计思维、技术细节
4.1 CQRS
- DDD 中的那些模式 — CQRS – 知乎
- 详解 CQRS 架构模式_架构_Kislay Verma_InfoQ 精选文章
Command Query Responsibility Segregation 即咱们艰深了解的读写拆散,其核心思想在于将两类不同操作进行拆散,在独立的服务中实现
用处在于将畛域模型与查问性能进行拆散,让一些简单的查问解脱畛域模型的限度,以更为简略的 DTO 模式展示查问后果。同时拆散了不同的数据存储构造,让开发者依照查问的性能与要求更加自在的抉择数据存储引擎
4.2 复制负载平衡服务
- 分布式系统设计: 服务模式之复制负载平衡服务 – 知乎
- 负载平衡调度算法大全 | 菜鸟教程
复制负载平衡服务(Replication Load Balancing Service, RLBS),能够简略了解为咱们常说的负载平衡,多个雷同的服务实例构建一个集群,每个服务都能够响应申请,负载均衡器负责申请的散发到不同的实例上,常见的负载算法
算法 | 阐明 | 特点 |
---|---|---|
轮询 | 申请依照程序顺次分发给对应的服务器 | 长处简略,毛病在于未思考不同服务器的理论性能状况 |
加权轮询 | 权重高的被散发更多的申请 | 长处:充分利用机器的性能 |
起码连接数 | 找连接数起码的服务器进行申请散发, 若所有服务器雷同的连接数,则找第一个抉择的 | 目标是让优先让闲暇的机器响应申请 |
少连接数慢启动工夫 | 刚启动的服务器,在一个时间段内,连接数是有限度且迟缓减少 | 防止刚上线导致大量的申请散发过去而超载 |
加权起码连贯 | 均衡服务性能 + 起码连接数 | |
基于代理的自适应负载平衡 | 载主机蕴含一个自实用逻辑用来定时监测服务器状态和该服务器的权重 | |
源地址哈希法 | 获取客户端的 IP 地址,通过哈希函映射到对应的服务器 | 雷同的起源申请都转发到雷同的服务器上 |
随机 | 随机算法抉择一台服务器 | |
固定权重 | 最高权重只有在其余服务器的权重值都很低时才应用。然而,如果最高权重的服务器降落,则下一个最高优先级的服务器将为客户端服务 | 每个实在服务器的权重须要基于服务器优先级来配置 |
加权响应 | 服务器响应越小其权重越高,通常是基于心跳来判断机器的快慢 | 心跳的响应并不一定十分精确反馈服务状况 |
4.3 心跳机制
在分布式环境里中,如何判断一个服务是否存活,当下最常见的计划就是心跳
比方 raft 算法中的 leader 向所有的 follow 发送心跳,示意本人还健在,防止产生新的选举;
比方 redis 的哨兵机制,也是通过 ping/pong 的心跳来判断节点是否下线,是否须要选新的主节点;
再比方咱们日常的业务利用得衰弱监测,判断服务是否失常
4.4 租约机制
租约就像一个锁,但即便客户端来到,它也能工作。客户端申请无限期限的租约,之后租约到期。如果客户端想要缩短租约,它能够在租约到期之前续订租约。
租约次要是了防止一个资源短暂被某个对象持有,一旦对方挂了且不会被动开释的问题;在理论的场景中,有两个典型的利用
case1 分布式锁
业务获取的分布式锁个别都有一个有效期,若有效期内没有被动开释,这个锁仍然会被开释掉,其余业务也能够抢占到这把锁;因而对于持有锁的业务方而言,若发现在到期前,业务逻辑还没有解决完,则能够续约,让本人持续持有这把锁
典型的实现形式是 redisson 的看门狗机制
case2 raft 算法的任期
在 raft 算法中,每个 leader 都有一个任期,任期过后会从新选举,而 Leader 为了防止从新选举,个别会定时发送心跳到 Follower 进行续约
4.5 Leader & Follow
这个比拟好了解,下面很多零碎都采纳了这种计划,特地是在共识算法中,由领导者负责代表整个集群做出决策,并将决策流传到所有其余服务器
领导者选举在服务器启动时进行。每个服务器在启动时都会启动领导者选举,并尝试选举领导者。除非选出领导者,否则零碎不承受任何客户端申请
4.6 Fencing
在领导者 - 追随者模式中,当领导者失败时,不可能确定领导者已进行工作,如慢速网络或网络分区可能会触发新的领导者选举,即便前一个领导者仍在运行并认为它依然是流动的领导者
Fencint 是指在以前处于活动状态的领导者四周设置围栏,使其无法访问集群资源,从而进行为任何读 / 写申请提供服务
- 资源屏蔽:零碎会阻止以前处于活动状态的领导者拜访执行根本工作所需的资源。
- 节点屏蔽:零碎会阻止以前处于活动状态的领导者拜访所有资源。执行此操作的常见办法是敞开节点电源或重置节点。
4.7 Quorum 法定人数
法定人数,常见于选举、共识算法中,当超过 Quorum 的节点数确认之后,才示意这个提案通过(数据更新胜利),通常这个法定人数为 = 半数节点 + 1
4.8 High-Water mark 高水位线
高水位线,跟踪 Leader(领导者)上的最初一个日志条目,且该条目已胜利复制到 >quorum(法定人数)的 Follow(跟谁者),即示意这个日志被整个集群承受
日志中此条目标索引称为高水位线索引。领导者仅公开到高水位线索引的数据。
如 Kafka:为了解决非可反复读取并确保数据一致性,Kafka broker 会跟踪高水位线,这是特定分区的最大偏移量。使用者只能看到高水位线之前的音讯。
4.9 Phi 累计故障检测
Phi Accrual Failure Detection, 应用历史检测信号信息使阈值自适应
通用的应计故障检测器不会判断服务器是否处于活动状态,而是输入无关服务器的可疑级别。
如 Cassandra(Facebook 开源的分布式 NoSql 数据库)应用 Phi 应计故障检测器算法来确定群集中节点的状态
4.10 Write-ahead Log 预写日志
预写日志记录是解决操作系统中文件系统不统一的问题的高级解决方案,当咱们提交写到操作系统的文件缓存,此时业务会认为曾经提交胜利;然而在文件缓存与理论写盘之间会有一个时间差,若此时机器宕机,会导致缓存中的数据失落,从而导致完整性缺失
为了解决这个问题,如 mysql,es 等都采纳了预写日志的机制来防止这个问题
MySql:
- 事务提交的流程中,先写 redolog precommit,而后写 binlog,最初再 redolog commit;当 redolog 记录胜利之后,才示意事务执行胜利;
- 因而当呈现下面的宕机复原时,则会加载 redologo,而后重放对应的命令,来复原未长久化的数据
ElasticSearch:
- 在内存中数据生成段写到操作系统文件缓存前,会先写事务日志,出现异常时,也是从事务日志进行复原
4.11 分段日志
将日志拆分为多个较小的文件,而不是单个大文件,以便于操作。
单个日志文件在启动时读取时可能会增长并成为性能瓶颈。较旧的日志会定期清理,并且很难对单个大文件执行清理操作。
单个日志拆分为多个段。日志文件在指定的大小限度后滚动。应用日志分段,须要有一种将逻辑日志偏移量(或日志序列号)映射到日志段文件的简略办法。
这个其实也十分常见,比方咱们理论业务利用配置的 log,个别都是按天、固定大小进行拆分,并不会把所有的日志都放在一个日志文件中
再比方 es 的分段存储,一个段就是一个小的存储文件
4.12 checksum 校验
在分布式系统中,在组件之间挪动数据时,从节点获取的数据可能会损坏。
计算校验和并将其与数据一起存储。
要计算校验和,请应用 MD5、SHA-1、SHA-256 或 SHA-512 等加密哈希函数。哈希函数获取输出数据并生成固定长度的字符串(蕴含字母和数字); 此字符串称为校验和。
当零碎存储某些数据时,它会计算数据的校验和,并将校验和与数据一起存储。当客户端检索数据时,它会验证从服务器接管的数据是否与存储的校验和匹配。如果没有,则客户端能够抉择从另一个正本检索该数据。
HDFS 和 Chubby 将每个文件的校验和与数据一起存储。
4.13 一灰灰的小结
这一节很多内容来自上面这篇博文,举荐有趣味的小伙伴查看原文
- Distributed System Design Patterns | by Nishant | Medium
这一节次要简略的介绍了下分布式系统中利用到的一些技术计划,如有对其中某个技术有趣味的小伙伴能够留言,后续会逐个进行补全
5. 分布式系统解决方案
最初再介绍一些常见的分布式业务场景及对应的解决方案,比方全局惟一的递增 ID- 雪花算法,分布式系统的资源抢占 - 分布式锁,分布式事务 -2pc/3pc/tcc,分布式缓存等
5.1 缓存
缓存实际上并不是分布式独有的,这里把它加进来,次要是因为切实是利用得太广了,无论是应用服务、根底软件工具还是操作系统,大量都能够见到缓存的身影
缓存的核心思想在于:借助更高效的 IO 形式,来代替代价低廉的 IO 形式
如:
- redis 的性能高于 mysql
- 如内存的读写,远高于磁盘 IO,文件 IO
- 磁盘程序读写 > 随机读写
用好缓存能够无效进步利用性能,上面以一个一般的 java 前台利用为例阐明
- JVM 缓存 -> 分布式缓存(redis/memcache) -> mysql 缓存 -> 操作系统文件缓存 -> 磁盘文件
缓存面临的外围问题,则在于
- 一致性问题:缓存与 db 的一致性如何保障(置信大家都据说过或者理论解决过这种问题)
-
数据完整性:比方常见的先写缓存,异步刷新到磁盘,那么缓存到磁盘刷新这段时间内,若宕机导致数据失落怎么办?
- TIP: 下面这个问题能够参考 mysql 的 redolog
5.2 全局惟一 ID
在传统的单体架构中,业务 id 基本上是依赖于数据库的自增 id 来解决;当咱们进入分布式场景时,如咱们常说的分库分表时,就须要咱们来思考如何实现全局惟一的业务 id 了,避免出现在分表中呈现抵触
全局惟一 ID 解决方案:
- uuid
- 数据库自增 id 表
- redis 原子自增命令
- 雪花算法 (原生的,扩大的百度 UidGenerator, 美团 Leaf 等)
- Mist 薄雾算法
5.3 分布式锁
罕用于分布式系统中资源管制,只有持有锁的能力持续操作,确保同一时刻只会有一个实例拜访这个资源
常见的分布式锁有
- 基于数据库实现分布式锁
- Redis 实现分布式锁(利用篇)| 一灰灰 Learning
- 从 0 到 1 实现一个分布式锁 | 一灰灰 Learning
- etcd 实现分布式锁
- 基于 consul 实现分布式锁
5.4 分布式事务
事务示意一组操作,要么全副胜利,要么全副不胜利;单机事务通常说的是数据库的事务;而分布式事务,则能够简略了解为多个数据库的操作,要么同时胜利,要么全副不胜利
更确切一点的说法,分布式事务次要是要求事务的参与方,可能波及到多个零碎、多个数据资源,要求它们的操作要么都胜利,要么都回滚;
一个简略的例子形容下分布式事务场景:
下单扣库存
- 用户下单,付钱
- 此时订单服务,会生成订单信息
- 领取网关,会记录付款信息,胜利 or 失败
- 库存服务,扣减对应的库存
一个下单领取操作,波及到三个零碎,而分布式事务则是要求,若领取胜利,则下面三个零碎都应该更新胜利;若有一个操作失败,如领取失败,则曾经扣了库存的要回滚(还库存),生成的订单信息回滚(删掉 – 注:事实中并不会去删除订单信息,这里只是用于阐明分布式事务,请勿带入理论的实现计划)
分布式事务实现计划:
- 2PC: 后面说的两阶段提交,就是实现分布式事务的一个经典解决方案
- 3PC: 三阶段提交
- TCC:弥补事务,简略了解为利用层面的 2PC
- SAGA 事务
- 本地音讯表
- MQ 事务计划
5.5 分布式工作
分布式工作相比于咱们常说单机的定时工作而言,能够简略的了解为多台实例上的定时工作,从利用场景来说,能够辨别两种
-
互斥性的分布式工作
- 即同一时刻,集群内只能有一个实例执行这个工作
-
并存式的分布式工作
- 同一时刻,所有的实例都能够执行这个工作
- 续思考如何防止多个工作操作雷同的资源
分布式工作实现计划:
- Quartz Cluster
- XXL-Job
- Elastic-Job
-
自研:
- 资源分片策略
- 分布式锁管制的惟一工作执行策略
5.6 分布式 Session
Session 个别叫做会话,Session 技术是 http 状态放弃在服务端的解决方案,它是通过服务器来放弃状态的。咱们能够把客户端浏览器与服务器之间一系列交互的动作称为一个 Session。是服务器端为客户端所开拓的存储空间,在其中保留的信息就是用于放弃状态。因而,session 是解决 http 协定无状态问题的服务端解决方案,它能让客户端和服务端一系列交互动作变成一个残缺的事务。
单机基于 session/cookie 来实现用户认证,那么在分布式系统的多实例之间,如何验证用户身份呢?这个就是咱们说的分布式 session
分布式 session 实现计划:
- session stick:客户端每次申请都转发到同一台服务器(如基于 ip 的 hash 路由转发策略)
- session 复制: session 生成之后,被动同步给其余服务器
- session 集中保留:用户信息对立存储,每次须要时对立从这里取(也就是常说的 redis 实现分布式 session 计划)
- cookie: 应用客户端 cookie 存储 session 数据,每次申请时携带这个
5.7 分布式链路追踪
分布式链路追踪也能够叫做全链路追中,而它能够说是每个开发者的福音,通常指的是一次前端的申请,将这个申请过程中,所有波及到的零碎、链路都串联起来,能够清晰的晓得这一次申请中,调用了哪些服务,有哪些 IO 交互,瓶颈点在哪里,什么中央抛出了异样
以后支流的全链路计划大多是基于 google 的Dapper
论文实现的
全链路实现计划
- zipkin
- pinpoint
- SkyWalking
- CAT
- jaeger
5.8 布隆过滤器
Bloom 过滤器是一种节俭空间的概率数据结构,用于测试元素是否为某汇合的成员。
布隆过滤器由一个长度为 m 比特的位数组(bit array)与 k 个哈希函数(hash function)组成的数据结构。
原理是当一个元素被退出汇合时,通过 K 个散列函数将这个元素映射成一个位数组中的 K 个点,把它们置为 1。
检索时,咱们只有看看这些点是不是都是 1 就大概晓得汇合中有没有它了,也就是说,如果这些点有任何一个 0,则被检元素肯定不在;如果都是 1,则被检元素很可能在。
对于布隆过滤器,请牢记一点
- 断定命中的,不肯定真的命中
- 断定没有命中的,则肯定不在外面
常见的利用场景,如
- 避免缓存穿透
- 爬虫时反复检测
5.9 一灰灰的小结
分布式系统的解决方案当然不局限于下面几种,比方分布式存储、分布式计算等也属于常见的场景,当然在咱们理论的业务反对过程中,不太可能须要让咱们本人来撑持这种大活;而下面提到的几个点,基本上或多或少会与咱们日常工作相干,这里列出来当然是好为了后续的详情做铺垫
6. 一灰灰的总结
6.1 综述
这是一篇概括性的综述类文章,可能并没有很多的干货,当然也限于“一灰灰”我集体的能力,下面的总结可能并不精确,如有发现,请不吝赐教
全文总结如下
常见的分布式架构设计计划:
- 主备,主从,多主多从,一般无核心集群,数据分片架构
分布式系统中的实践基石:
- CAP,BASE, PACELEC
- 共识算法:paxos, raft, zab
- 一致性协定:2pc, 3pc
- 数据同步:gossip
分布式系统中的算法:
- 分区的一致性 hash 算法: 基于 hash 环,缩小节点动静减少缩小对整个集群的影响;实用于数据分片的场景
- 实用于一致性的 Quorum NWR 算法: 投票算法,定义如何就一个提案达成共识
- PBFT 拜占庭容错算法: 实用于集群中节点故障、或者不可信的场景
- 区块链中大量应用的工作量证实 PoW 算法: 通过工作量证实,认可节点的提交
分布式系统解决方案:
- 分布式缓存
- 全局惟一 ID
- 分布式锁
- 分布式事务
- 分布式工作
- 分布式会话
- 分布式链路追踪
- 布隆过滤器
6.2 题外话
最初总结一下这篇耗时两周写完的“心血巨作”(有点自吹了哈),筹备这篇文章的确花了很大的精力,首先我集体对于分布式这块的了解并不能算粗浅,其次分布式这块的实践 + 实际常识特地多,而且并不是特地容易上手了解,在输入这篇文章的同时,遇到一些疑难点我也会去查阅相干材料去确认,整个过程并不算特地顺利;那么为什么还要去做这个事件呢?
- 咸鱼太久了,想做一些有意思的货色,沉闷一下大脑
- 筹备依靠于《分布式专栏》来将本人的常识体系进行演绎汇总,让零散散布在大脑中的知识点能有一个脉络串联起来
- 不想做架构的码农不是好码农,而想成为一个好的架构,当然得做一些根底筹备,向业务精品学习取经