分布式系统原理

CAP定理

C Consistency,一致性

A Availability,可用性

P partition tolerance,分区容错性

只能同时满足两个

BASE理论

Basically Available(基本可用):系统出现故障时,允许损失部分可用性

Soft state软状态:允许系统中的数据存在中间状态,且不影响整体可用性,允许系统在多个节点的数据副本之间进行同步的过程中存在延迟

Eventually consistent(最终一致性):系统保证最终数据能够达到一致

一致性协议2PC

2是两个阶段;P是准备阶段,C是提交阶段

准备阶段:事务管理器发送prepare消息给每个参与者,参与者在本地执行事务并编写undo/redo,此时事务没有提交

提交阶段:事务管理器收到参与者执行失败或超时的消息,发送回滚给每个参与者,否则发送提交;参与者根据命令执行回滚或提交并释放锁

缺点:1同步阻塞,需要每个阶段全部完成才能进入下一个阶段;2依赖事务管理者,如果管理者在提交中途宕机会发生数据不同步,且管理者只能依赖超时进行中断

一致性协议3PC

由 CanCommit、PreCommit和doCommit三个阶段组成的事务处理协议

CanCommit:协调者给参与者发送事务响应等待全部回应。

PreCommit:协调者收到全部参与者响应,yes发送执行事务预提交,并反馈ACK,如果有一个参与者未反馈或者反馈no,中断事务。

doCommit:协调者收到所有参数值ACK反馈,向所有参与者发送提交指令,参与者完成之后向协调者发送ACK响应

2PC和3PC对比

1为参与者也设立了超时机制,降低了整个事务的阻塞时间和范围,

2三个阶段,确保docommit之前,各个节点状态一致

3没有完全解决数据不一致问题

一致性算法Paxos

用来解决数据不一致问题

使用提案和决策来进行一致性处理

使用协调者集群(由决策者构成)

  1. 客户端发送请求
  2. 提案发起者提倡客户请求,并试图说服决策者
  3. 决策者超过半数同意就接收该提案
  4. 学习者充当复制因素

一致性保证:

1)在这些被提出的提案中,只有一个会被选定 。

2)如果没有提案被提出,就不应该有被选定的提案。

3)当一个提案被选定后,那么所有进程都应该能学习(learn)到这个被选定的value

选定一个主的提案发起者来保持活性,避免两个提案发起者相互递增序号引起死循环

一致性算法Raft

两个阶段:1选举,2由选举人进行操作

选举

领导者,候选人,跟随者

所有服务器初始状态为跟随者,有一个定时器,一旦超时,则状态变为候选人,并发送消息给其他服务器,如果收到超过半数的返回,则成为领导者,开始根据间隔时间发送心跳检测包证明自己还活着(心跳机制),若一段时间没发出心跳检测包,其他服务器的定时器超时,则变为候选人,重复上述步骤直到选出领导者

日志复制(保证数据一致性)

领导人接收客户端请求,将请求作为日志条目加入它的日志中,向并行的其他服务器发送AppendEntries RPC复制日志条目,当该条目复制到大多数服务器上,将该日志应用到它的状态机并向客户端返回执行结果

1)客户端的每一个请求都包含被复制状态机执行的指令。

2)leader把这个指令作为一条新的日志条目添加到日志中,然后并行发起 RPC 给其他的服务器,让他们复制这条 信息。

3)跟随者响应ACK,如果 follower 宕机或者运行缓慢或者丢包,leader会不断的重试,直到所有的 follower 最终都 复制了所有的日志条目。

4)通知所有的Follower提交日志,同时领导人提交这条日志到自己的状态机中,并返回给客户端。

常用的分布式设计策略:

心跳检测机制

定期发送心跳

高可用设计

主备:一般使用主服务器,当主服务器宕机,使用备份服务器,主服务器恢复后使用热备份或者冷备份将服务切换到主服务器上运行

互备:两台服务器相互监测,运行各自的服务工作,相互备份同步,用途:对写入要求高,需要多台服务器储存写入数据

集群:多个节点在运行,通过主控节点分担服务请求,需要解决主控节点的高可用问题,一般采取主备将某个节点作为主控节点

容错性设计

提高系统对于错误包容的能力,保障分布式环境下相应系统的高可用或者健壮性,也提升了系统的安全性。

例如radis的缓存穿透,当请求的数据在缓存中不存在时,才去服务器数据库查询

负载均衡策略

1轮询,nginx采用该方案作为默认,根据配置文件中的顺序,依次将请求发送到不同的后端服务器

2最少链接:谁的链接最少发送给谁

3IP地址哈希:确定相同IP的请求可以发送给同一个服务器,方便session保持

4基于权重的负载均衡:配置nginx,把请求更多的发送到高配服务器上

网络通信

RPC远程过程调用

四个组件,服务器,服务器存根,客户端存根,客户端

1) 客户端以接口方式调用客户端存根。

2) 客户端存根收到调用后,把方法、参数等封装成消息体进行序列化成二进制文件,从而在网络中传输。

3) 客户端存根将请求发送给服务器存根。

4) 服务器存根收到消息后对消息体进行反向序列化。

5) 服务端存根根据解码结果调用本地服务端。

6) 服务端进行服务处理,即执行方法并返回结果。

7) 服务端存根收到结果,将结果封装成消息体,并进行序列化成二进制文件。

8) 服务端存根返回消息给客户端存根。

9) 客户端存根收到消息后对消息体进行反序列化解码。

10)客户端存根返回解码结果,客户端得到最终结果。

需要封装234 789

RMI远程方法调用

采用JRMP(Java Remote Messageing protocol)作为通信协议,纯java版本的分布式远程调用解决方案。

客户端

1)存根/桩(Stub):远程对象在客户端上的代理。

2)远程引用层(Remote Reference Layer):解析并执行远程引用协议。

3)传输层(Transport):发送调用、传递远程方法参数、接收远程方法执行结果。

服务端

1) 骨架(Skeleton):读取客户端传递的方法参数,调用服务器方的实际对象方法,并接收方法执行后的返回值。

2) 远程引用层(Remote Reference Layer):处理远程引用后向骨架发送远程方法调用。

3) 传输层(Transport):监听客户端的入站连接,接收并转发调用到远程引用层。

使用一个注册表来链接客户端和服务端之间的调用

服务端启动时向注册表中发布对象,再启动客户端,客户端从注册表中获取远程对象的引用,接着客户端生成代理对象stub,通过远程引用层转化成远程应用对象,传给传输层,再发送到服务端传输层, 服务端的远程应用层将其转化为服务端本地对象,再发送给骨架进行对应方法的调用和结果获取,最后将执行结果通过上述步骤反方向返回

同步、异步、阻塞、非阻塞

同步:用户进程触发IO操作等待或者轮训的方式查看IO操作是否就绪

异步:当一个异步进程调用发出之后,调用者不会立刻得到结果。而是在调用发出之后,被调用者通过状态、通知来通知调用者,或者通过回调函数来处理这个调用

阻塞:当一个线程需要获取一把锁,一直等待这个锁释放。

非阻塞:当一个线程需要获取一把锁,并不会一直等待,他跑去做其他事,等通知者告知他锁被释放,他在回来获取锁接着干事

BIO同步阻塞IO

一个连接一个线程,连接增多时,线程增多,且空线程浪费资源

NIO同步非阻塞IO

一个请求一个通道,即客户端发送的连接请求都会注册到多路复用器上,多路复用器(也称为选择器)轮询到连接有IO请求时才启动一个线程进行处理。

即一个多路复用器控制多个链接,检测到IO请求时才处理,避免了BIO的多线程重复循环检测

AIO异步非阻塞IO

当有流可以读时,操作系统会将可以读的流传入read方法的缓冲区,并通知应用程序,对于写操作,OS将write方法的流写入完毕,操作系统会主动通知应用程序。因此read和write都是异步的,完成后调用回调函数通知

posted on 2025-08-11 13:36  chycal  阅读(13)  评论(0)    收藏  举报