分布式学习笔记

1. CAP理论

Consistency(一致性):用户访问分布式系统中的任意节点,得到的数据必须一致。

Availability(可用性):用户访问集群中的任意健康节点,必须得到相应,而不是超时或拒绝。

Partition tolerance (分区容忍性):因为网络故障或其他原因导致分布式系统中的部分节点与其他节点失去连接,形成独立分区。在集群出现分区时,整个系统也要持续对外提供服务。

2. 一致性级别

CP和AP之间需要做权衡,其实根据需求不同,也可以将一致性划分为几个级别,在这些级别里面做一个权衡

  1. 强一致性:系统写入什么,读出来的也会是什么,但实现起来往往对性能影响较大

    例如:火车站购票,有就是有,没有就是没有,不能出现不一致的情况

    典型算法:PaxosRaftZAB

  2. 弱一致性:系统写入成功后,不承诺立刻可以读到写入的值,也不承诺具体多久后数据能达到一致,还可以细分为:

    • 会话一致性:同一个客户端会话中可以保证一致,其他会话不能保证
    • 用户一致性:同一个用户中可以保证一致,其他用户不能保证

    例如:网上购物,在商品详情页看到库存还有好多,下单的瞬间才被提示"库存数量不足",实际上商品详情页展示的库存并不是最新的数据,只是在某个流程上才会做准确的检查

  3. 最终一致性:是弱一致性的特例,保证在一定时间内,能够达到一个一致的状态

    例如:转账,转账完成后,会有一个提示,您的转账会在24小时内到账,一般用户也能接受,但最终必须是一致的

    典型算法:Gossip

3. Paxos 算法

3.1 问题引入

集群中有N个节点,如果一个节点写入后要求同步到剩余N - 1个节点后再向客户端返回 OK,虽然看起来最保险,但其中任意一个节点同步失败,势必造成整个集群不可用,能否在此基础上稍微提高可用性呢?
在这里插入图片描述

我们可以在写操作的时候,采用多数派的思想:集群节点设置为奇数,同步超过集群中 N / 2 个节点成功,则向客户端返回 OK。(你可能会疑惑当这 N / 2 个节点是写成功了,如果此时访问到剩余那些没有同步成功的数据怎么办?这里我们先简化一下问题,暂不考虑多数派写成功后的读一致性

采用多数派思想其实还存在问题:顺序性问题

在这里插入图片描述
如上图,当S1服务器发送一个自增命令以后,此时S5服务器发送了一个set x 0指令,S2和S3服务器是正常自增了,但S3服务器的 x值 先被设置为 0 ,后又因为顺序性问题自增为1,虽然这两次操作都返回了 OK,但此时就产生了各个服务器之间的数据的不一致。

3.2 角色划分和阶段划分

Paxos是一种共识算法,目的是解决之前提到的强一致性问题。

Paxos角色划分:集群中的每个节点都可以充当

  1. Proposer:负责生成提案

    注意:Paxos 算法允许有多个 Proposer 同时提案,但可能会引起活锁问题

  2. Acceptor:负责批准提案

    Acceptor 如果只有一个的话,存在单点问题,因此应当有多个

  3. Learner:负责获取提案,Acceptor批准提案以后,会将提案发送给所有 Learner

Paxos阶段划分:

执行一个修改操作,不是一上来就能执行

  1. 准备阶段:Proposer 发起提案以后,必须由多数派 Acceptor 批准通过后才能进入接受阶段
  2. 接受阶段:Proposer 需要再将要执行的修改操作,广播给 Acceptor,这次仍然多数派通过,此修改才能生效,可以返回响应给客户端

3.3 Basic Paxos 算法描述

在这里插入图片描述
要点:

  • 整个算法分成两个阶段:预备阶段,前两个箭头,接受阶段,后两个箭头

    预备阶段的目的:第一拦截掉旧的方案第二找到最新的 acceptValue

  • 对于 Proposer

    • 预备阶段只发送提案号,接受阶段发送提案号 + 值
    • 提案号 n 唯一且全局递增,大的提案号有更高的优先级
    • 如果见到最新已经接受的值的值,就会替换掉 Proposer 自己的值,保证一致性
  • 对于 Acceptor 会持久化以下信息

    • minN(最小提案号),会在预备阶段和接受阶段被更新为更大的提案号,会用来决定 Proposer 是否能选中提案
    • acceptN(已接受提案号)和acceptValue(已接受值),会在接受阶段被更新,如果 minN > n 则不会更新

3.4 顺序性问题回顾

Paxos 算法通过预备接受两个阶段来解决一致性问题。

情形一:
在这里插入图片描述
情形二:
在这里插入图片描述

3.5 缺点

1.效率比较低,两轮操作只能选中一个值

2.难于理解,算法比较复杂难懂

3.活锁问题

例如:
在这里插入图片描述

S1 的 1 号提案会被 S5 的 2 号提案所影响,导致 1 号提案作废,同样的 S5 的 2 号提案也会被 S1 的 3 号提案所影响导致 2 号提案被作废,如此循环导致提案都被废弃,这就是 Paxos 的活锁问题。

4. Raft 算法

另一种强一致性算法(共识算法),目的是比 Paxos 更容易理解

Raft 算法演示网站:https://raft.github.io/raftscope/index.html

整个 Raft 算法分解成三不分:

  1. Leader 选举:
    • 只有一个 Server 能作为 Leader
    • 一旦此 Server 崩溃,选举新的 Leader
  2. 执行操作(以日志复制为例,Log Replication)
    • 由 Leader 执行自己的日志记录
    • 将日志复制到其他 Server,以Leader 的日志为准,会覆盖 Server 中不一致的部分
    • 多数派记录日志成功,Leader 才能执行命令,向客户端返回结果
  3. 确保安全
    • 确保日志记录的一致性
    • 拥有最新日志的 Server 才能成为 Leader

4.1 Leader 选举

  1. Leader 会不断向选民发送 AppendEntries 请求,证明自己还活着
  2. 选民收到 LeaderAppendEntries 请求后会重置自己的 timeout 时间
  3. 选民收不到 AppendEntries 请求超时后,转换角色为候选者,并将任期加 1,发送 RequestVote 请求,推选自己
  4. 选民收到第一个 RequestVote,会向该候选者投一票,这样即使有多个候选者,必定会选出一个 Leader,选票过半即当选,落选后变回选民
  5. 每一任期最多有一个 Leader,但也可能没有(选票数不过半的情况,需要再进行一轮投票,timeout在 T~2T 之间随机,timeout时间过短会导致 Leader仍然存活时重新选举,时间过长会导致选举时间变长,整个系统响应速度变慢,T是指两个节点之间的通信时间)
  6. 任期由各个 server 自己维护即可,无需全局维护,在超时后 + 1,在接收到任意消息时更新为更新的任期,遇到更旧的任期,视为错误

4.2 执行操作(日志复制为例)

  1. 客户端发送命令到 Leader
  2. Leader将命令写入日志
  3. Leader向所有选民发送 AppendEntries 请求
    • 在多数派通过后,执行命令(即提交),向客户端返回结果
    • 在后续的 AppendEntries 请求中通知选民
    • 选民执行命令(即提交)

4.3 确保安全

Leader 日志的完整性

  1. Leader 被认为拥有最完整的日志
  2. 一旦 Leader 完成了某条命令的提交,那么未来的 Leader 也必须有该条命令提交信息
  3. 投票时,会将候选者最新的 <Term,Index>随 RequestVote 请求发送,如果候选者的日志还没选民的新,则投否决票

选民日志的一致性

  1. 以 Leader 为例,对选民的日志进行补充或覆盖
  2. AppendEntries 请求发送时会携带最新的<Term, Index, Commend>以及上一个的<Term, Index>
  3. 如果选民发现上一个的<Term, Index>能够对应上则成功,否则失败,继续携带更早的信息进行比对

5. Gossip 协议

与 Paxos 和 Raft 目标是强一致性不同,Gossip 达到的是最终一致性

A gossip protocol is a procedure or process of computer peer-to-peer communication that is based on the way epidemics spread.

它可以快速的将信息散播给集群中每个成员,散播速度为log N(实际传播次数可能会高于此结果,因为随机时会随到一些重复的成员)

优点:

  • 扩展性高,传播次数不会受集群成员增长而增长过快
  • 容错性好,即使某些节点间发生了故障无法通信,也不会影响最终的一致性
  • Robust(鲁棒性),即皮实,集群中的节点是对等的,即便一些节点挂了,一些节点添加进来,也不会影响其他节点的信息传播

6. 分布式通用设计

6.1 如何监测节点活着?

向节点周期性发送心跳请求,如果能收到心跳回应,表示该节点还活着

如果收不到心跳回应,却不能证明该节点了,可能由于网络抖动、回应延时等原因没能及时收到回应。有如下解决思路:

  • 如 Redis 哨兵模式中,如果 sentinel 向 master 发送 PING 而没有收到 PONG,整你判断主观下线,必须采用其他 sentinel 的意见,达到多数派后才能判断客观下线,进入主备切换流程
  • 将周期心跳检测升级为累计心跳检测机制,即记录统计该节点的历史响应时间,如果超过警戒,则发起有限次数的重试作为进一步判定

6.2 如何保证高可用?

应用层高可用:

关键是做到无状态,即所有节点地位平等,去 session 化。利用负载均衡将请求发送到任意一台节点进行处理,如果有某个节点宕机,把该节点从服务列表中移除,不会影响业务运行。

服务层高可用:

同样要做到无状态,此外还应当考虑

  • 核心服务和非核心服务隔离部署,分级管理,方便非核心服务降级
  • 对于即时性没有要求的服务可以考虑采用异步调用优化
  • 合理设置超时时间,在超时后应当有对应的处理策略,如:重试、转移、降级等

数据层高可用:

需要有数据备份机制与故障转移机制

缓存服务是否需要高可用,两种观点:

  1. 缓存服务不可用会让数据库失去保护,因此需要保证缓存服务高可用
  2. 缓存服务不是数据存储服务,缓存宕机应当通过其他手段解决,如扩大缓存规模,一个缓存服务器的宕机只会影响局部

6.3 如何实现全局唯一ID?

Redis:

  • 使用 incr 生成 id,由于 Redis 的单线程特性,能保证它不会重复
  • 缺点:属于集中式的解决方案,有网络消耗

UUID:

  • UUID有多种实现,典型的UUID实现会包含时间信息、MAC地址信息、随机数
  • 优点:属于本地解决方案,无网络消耗
  • 缺点:MAC地址提供了唯一性的保证,但也带来安全风险,最糟的是它是字符串形式,占用空间大,查询性能低,无法保证趋势递增

Snowflake(推荐):

  • 通常的实现是 41 位时间信息、精确到毫秒,10 位的机器标识、12 位的序列号,还有 1 位没有使用,共 8 个字节
  • 理解思想以后,可以根据自己实际情况对原有算法做调整
  • 优点:本地解决方案,无网络小号。长整型避免了字符串的缺点,并保证了趋势递增

6.4 负载均衡算法

负载均衡算法用于在多个服务器或节点间分发工作负载,以确保各个节点能够有效地处理请求,提高系统的性能和可靠性。以下是一些常见的负载均衡算法:

  1. 轮询(Round Robin)

    • 将请求依次分配给每个节点,循环往复。每个请求按照顺序分发给不同的节点,适用于节点性能相近的情况。
  2. 加权轮询(Weighted Round Robin)

    • 类似于轮询算法,但给不同节点分配不同的权重,使得性能更高的节点能够处理更多的请求。
  3. 随机算法(Random)

    • 随机选择一个节点来处理请求,适用于节点性能相差不大且请求相对均匀的场景。
  4. 最少连接(Least Connections)

    • 将请求分配给当前连接数最少的节点。这种方式可以避免请求集中在少数节点上,适用于长连接或处理时间较长的场景。
  5. IP哈希(IP Hash)

    • 根据请求的源IP地址进行哈希计算,然后将相同哈希结果的请求发送到同一节点。这种方法可以确保同一客户端的请求始终发送到同一个节点,适用于需要保持会话一致性的场景。
  6. 最优响应时间(Least Response Time)

    • 根据节点的实时负载情况和响应时间选择最优节点。这需要实时监控节点的负载和性能指标来进行决策。
  7. 最少流量(Least Traffic)

    • 分配请求到当前流量最小的节点,确保整个系统的网络流量尽量均衡。
  8. 一致性哈希(Consistent Hashing)

    • 根据请求的键值对将请求映射到节点,通过哈希环的方式确定请求应该由哪个节点处理。这种算法在节点动态变化时能够更好地保持负载均衡。

6.5 数据分片策略

所谓分片就是指数据量较大时,对数据进行水平切分,让数据分布在多个节点上

1. Hash

  • 按照 key 的 hash 值将数据映射到不同的节点上
  • 优点:实现简洁、数据分布均匀
  • 缺点1:如果直接 hash 与节点数取模,节点变动时就会造成数据大规模迁移,可以使用一致性 hash 改进
  • 缺点2:查询某一类热点数据时,由于它们是用 hash 分散到了不同的节点上,造成查询效率不高

2. Range

  • 可以将 key 按照range 进行划分,让某一范围的数据都存放在同一节点上
  • 优点1:按照 range 查询,性能更高
  • 优点2:如果配合动态 range 分片,可以将较小的分片合并、将热点数据分散,有很多有用的功能

3. 静态调度和动态调度

  • 静态意味着数据分片后分布固定,即使移动也需要人工介入
  • 动态意味着通过管理器基于调度算法在各个节点之间自由移动数据

7. 分布式事务解决方案

7.1 两阶段提交(2PC)

两阶段提交(2PC):

  • 阶段1 - 准备阶段(Prepare Phase)

    1. 协调者(Coordinator)向所有参与者(Participants)发送准备请求,并等待它们的响应。
    2. 参与者收到请求后,执行事务操作,并将准备就绪的消息或“同意”响应返回给协调者。
  • 阶段2 - 提交或回滚阶段(Commit or Rollback Phase)

    1. 如果所有参与者都准备就绪,协调者向所有参与者发送提交请求,并等待它们的响应。
    2. 参与者收到提交请求后,如果事务执行成功,则提交事务并发送“提交完成”响应;如果执行失败,则回滚事务并发送“回滚完成”响应。
      在这里插入图片描述

缺点:

  • 阻塞型协议:所有参与者在等待接到下一步操作前,都处于阻塞,占用的资源也一直被锁定
  • 数据不一致:在阶段二,如果只有部分参与者收到的提交请求,则会造成数据不一致
  • 协调者单点问题:如果协调者故障在阶段二出现问题,会导致所有参与者(不会超时)始终处于阻塞状态,资源也被锁定得不到释放

7.2 TCC(事务预留)

TCC模式分成三个阶段:

  • Try:资源检查和预留

  • Confirm:业务执行和提交

  • Cancel:预留资源的释放

优点:

  • 一阶段完成直接提交事务,释放数据库资源,性能好
  • 不依赖数据库事务,而是依赖补偿操作,可以用于非事务型数据库

缺点:

  • 有代码侵入,需要人为编写try、confirm和cancel接口,太麻烦
  • 软状态,事务是最终一致
  • 需要考虑confirm和cancel的失败情况,做好幂等处理

7.3 基于可靠性消息的最终一致性方案

2PC 和 TCC 都属于同步方案,实际开发中更多采用的是异步方案

我们可以将问题转换为本地事务与消息投递的原子性

例如:下单以后得支付、扣减库存、增加积分等操作对实时性要求并不高。此时将下单成功的消息写入消息中间件,利用消息中间件实现最终一致性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/394349.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VSCODE上使用python_Django

接上篇 https://blog.csdn.net/weixin_44741835/article/details/136135996?csdn_share_tail%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22136135996%22%2C%22source%22%3A%22weixin_44741835%22%7D VSCODE官网&#xff1a; Editing Python …

汽车网络安全--关于供应商网络安全能力维度的思考

目录 1.关于CSMS的理解 2.OEM如何评审供应商 2.1 质量评审 2.2 网络安全能力评审 3.小结 1.关于CSMS的理解 最近在和朋友们交流汽车网络安全趋势时&#xff0c;讨论最多的是供应商如何向OEM证明其网络安全能力。 这是很重要的一环&#xff0c;因为随着汽车网络安全相关强…

AI 文生图提示词分类(合集 · 第一季)

一、时间和季节 Time and Season 1、时间描述 Time Description 比如&#xff0c;日出、黄昏、夜晚、清晨 / Sunrise, Sunset, Night, Early Morning 2、季节变化 Seasonal Changes 比如&#xff0c;春天、夏天、秋天、冬天 / Spring, Summer, Autumn, Winter 二、场景描述 Sce…

UE5中的DataTable说明

创建DataTable 在编辑器中创建 在文件夹空白处右击&#xff0c;选择Miscellaneous/DataTable&#xff0c;如图&#xff1a; 使用代码创建 // 创建DataTable实例 UDataTable* MyDataTable NewObject(); // 创建一个行结构体 UStruct* RowStruct UStruct::CreateEmpty(); // 添…

字符设备驱动分步注册实现LED驱动的编写

头文件 #ifndef __HEAD_H__ #define __HEAD_H__ typedef struct{unsigned int MODER;unsigned int OTYPER;unsigned int OSPEEDR;unsigned int PUPDR;unsigned int IDR;unsigned int ODR; }gpio_t;#define RCC 0x50000A28 #define LED1_ADDR 0x50006000 #defi…

序列发生器

一开始想直接FSM&#xff0c;划分出6状态依次输出对应的。但其实只要6比特的移位寄存器&#xff0c;每次输出高位。复位后的默认值时6’b001_011。这样就可以实现循环&#xff0c;这种移位寄存器也叫barrel_shifter。循环移位。也可以使用循环计数器&#xff0c;然后case计数器…

MATLAB知识点:meshgrid函数(★★★★☆)返回二维网格坐标(在MATLAB中经常用于生成绘制三维图的数据)

讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 节选自第3章&#xff1a;课后习题讲解中拓展的函数 在讲解第三…

从 AGP 4.1.2 到 7.5.1——XmlParser、GPathResult、QName 过时

新年首发&#xff0c; 去年的问题&#xff0c;今年解决~ 问题 & 排查 1: Task failed with an exception. ----------- * What went wrong: Execution failed for task :app:processCommonReleaseManifest. > org.xml.sax.SAXParseException; lineNumber: 1; columnNu…

Java学习--黑马SpringBoot3课程个人总结-2024-02-15

1.未登录统一处理 2.添加文章分类 //控制添加分类弹窗 const dialogVisible ref(false)//添加分类数据模型 const categoryModel ref({categoryName: ,categoryAlias: }) //添加分类表单校验 const rules {categoryName: [{ required: true, message: 请输入分类名称, tri…

element 表单提交图片(表单上传图片)

文章目录 使用场景页面效果前端代码 使用场景 vue2 element 表单提交图片   1.点击【上传图片】按钮择本地图片&#xff08;只能选择一张图片&#xff09;后。   2.点击图片&#xff0c;支持放大查看。   3.点击【保存】按钮&#xff0c;提交表单。 页面效果 前端代码…

OBD部署OceanBase集群-配置文件方式

前一篇文章介绍了OBD白屏可视化方式部署OceanBase集群 &#xff0c;其原理是把可视化设置生成为一个配置文件&#xff0c;然后使用OBD命令部署集群 本篇想使用命令行加配置文件方式&#xff0c;只部署OceanBase和ODProxy两个组件 服务器参数配置和 oceanbase-all-in-one-*.ta…

洛谷: P1553 数字反转(升级版)

思路: 没想到什么好办法&#xff0c;一步一步来。整体就是反转&#xff0c;删除前导/后导0&#xff0c;反转&#xff0c;删除前导/后导0。 第一次AC没过去&#xff0c;原因是没考虑到分数的分母前导0的情况&#xff0c;比如1234567890/1234567890这个样例&#xff0c;结果输出…

2024 ICDE第一轮 时空(Spatial-Temporal)和时序(Time Series)论文总结

ICDE 2024目前把第一轮接收的论文已经全部放出&#xff0c;部分挂在了arXiv上&#xff0c;本文总结了ICDE 2024第一轮有关时空和时序的相关文章。 &#x1f31f;【紧跟前沿】“时空探索之旅”与你一起探索时空奥秘&#xff01;&#x1f680; 时空数据&#xff08;Spatial-Tem…

MySQL系列之索引入门(下)

前言 通过上文&#xff0c;我想各位盆友已熟悉MySQL的索引分类及其含义&#xff0c;那么如何合理的使用呢&#xff1f; 请继续围观此文&#xff0c;一探究竟&#xff01; 一、创建索引 首先&#xff0c;我们一起学习索引是如何创建的&#xff0c;又有哪些方式。 1. create t…

104.网游逆向分析与插件开发-网络通信封包解析-接收数据的初步逆向分析

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;网络完成端口模型的流程 下图登录了游戏&#xff0c;此时此刻 WSARecv 已经投递 然后打开x96dbg来到WSARecv函数 然后WSARecv的线程id&#xff1a;5BAC WSASend函数的线程id&#xff1a;主线程 66C0 …

stm32--笔记

一、引脚与变量 ​​​​​​​​​​​​​​ 二、STM32时钟 [STM32-时钟系统详解_stm32时钟_KevinFlyn的博客-CSDN博客] 三、定时器中断实验 1、定时器中断实验 ​ stm32关于通用定时器的周期、频率计算公式_stm32tim频率计算_胶囊咖啡的博客-CSDN博客 ​ 【STM32】通用…

Eclipse - 查看工程或者文件的磁盘路径

Eclipse - 查看工程或者文件的磁盘路径 1. Help -> Eclipse Marketplace -> Find: Explorer -> Eclipse Explorer 4.1.0 -> Install2. right-click -> Open in ExplorerReferences 1. Help -> Eclipse Marketplace -> Find: Explorer -> Eclipse Explo…

svg图片构造QGraphicsSvgItem对象耗时很长的问题解决

目录 1. 问题的提出 2. 问题解决 1. 问题的提出 今天通过一张像素为141 * 214&#xff0c;大小为426KB的svg格式的图片构造QGraphicsSvgItem对象&#xff0c;再通过Qt的Graphics View Framework框架&#xff0c;将QGraphicsSvgItem对象显示到场景视图上&#xff0c;代码如下&…

【Python】【Pycharm】Python Script头文件设置

1、步骤&#xff1a;File->settings->Editor->File and CodeTemplates->Python Script 2、复制粘贴以下代码&#xff0c;应用即可&#xff1a; #!/usr/bin/env python # -*- coding: utf-8 -*-# Time :${DATE} ${TIME} # Author : admin # Site :${SITE} …

Hack The Box-Office

端口扫描&信息收集 使用nmap对靶机进行扫描 nmap -sC -sV 10.10.11.3开放了80端口&#xff0c;并且注意到该ip对应的域名为office.htb&#xff0c;将其加入到hosts文件中访问之 注意到扫描出来的还有robots文件&#xff0c;经过尝试后只有administrator界面是可以访问的 …