分布式架构
高可用架构
- 主从架构
 - 分布式架构
 
ps:分布式架构容易出现脑裂问题
分布式架构的中心化和去中心化
- 中心化:只能有一个主节点负责写入操作
- elasticsearch
 
 - 去中心化:每个主节点都可以负责写入操作
- redis
 
 
ps:中心化架构可以使用zookeeper来存储元数据和选举领导者
ps:中心化架构受限于单点的能力
ps:去中心化架构需要频繁的交换信息
节点的角色
- 主从架构
- master:主(一个),负责干活
 - slave:从(多个), 负责备用
 - sentinel:哨兵(多个),负责监工
 
 - 分布式架构
- leader:领导者(一个),负责决策
 - follower:跟随者(多个),负责备用
 - worker:工作者(多个):负责干活
 
 
ps:主从架构中写操作只能由master处理,读操作master和slave都可以处理
ps:分布式架构中写操作只能由leader处理,读操作leader和follower都可以处理
集群和分布式的区别
- 单机(Standalone):一个人干所有的事
 - 集群(Cluster):多个人
轮流干一件事 - 分布式(Distributed):多个人
分工干一件事 
ps:服务是集群(集群对应的是单机),计算和存储是分布式
分布式理论
CAP理论
- CAP
- C:强一致性:某个时刻读取所有节点的某个数据都是相同的(强一致性,不同于弱一致性和最终一致性)
 - A:高可用性:在有限的时间返回数据(不能出现等待延迟或者访问超时的情况)
 - P:分区容错性:网络故障出现分区后各个可用分区也能继续对外提供服务(而不是暂停服务去等待网络恢复)
 
 
ps:在分布式系统中,因为网络的复杂性,所以一定会出现因为网络故障导致分区的情况,如果此时不保证分区容错性,就意味着允许部分节点不可用导致服务不能提供完整的服务,但是大部分得场景是不能忍受不完整的服务的,所以分布式系统中一般会保证分区容错性
BASE理论
- BASE
- BA:基本可用
 - S:软状态(允许有短暂的中间状态)
 - E:最终一致性
 
 - ACID
- A:原子性
 - C:一致性
 - I:隔离性
 - D:持久性
 
 
ps:BASE理论的一致性是最终一致性,而CAP和ACID的一致性是强一致性
分布式算法
一致性算法
- 分布式强一致性算法
- Paxos
 - Raft(Paxos的简化版)
 - ZAB(为zookeeper专⻔设计的)
 
 - 分布式弱一致性算法
- Gossip
 
 
一致性hash
- 普通hash
 - 一致性hash
 - hash槽
 
ps:一致性hash和hash槽能够很好的支持节点的扩容和缩容
ps:节点路由(node route)问题是通过hash算法来解决的
ps:节点故障(node failure)问题则是通过主从架构来解决的
分布式协同
分布式协同又叫分布式协调
zookeeper能做什么
- 配置管理
 - 服务管理
 - 命名服务
 - 节点选举
 - 分布式锁
 
主从选举
数据同步
- 元信息同步
- 加入集群通知
 - 离开集群通知
 - 主节点选举
 
 - 健康状态同步
 
分布式计算
分布式计算模型
- fork-join
 - partition-merge
 
分布式计算框架
分布式存储
- replication(复制)
 - shard(分片)
 - replica(副本)
 
分布式应用
分布式ID
唯一标识生成器又叫发号器
唯一标识来源
- 业务id(身份证号、手机号、设备指纹)
 - 逻辑id(发号器生成)
- 顺序id
 - 随机id
 
 
唯一标识实现
- 单机
- 顺序id
- mysql自增id
 - 时间戳
 
 - 随机id
- UUID
 
 
 - 顺序id
 - 分布式
- 顺序id
- mysql发号器
 - redis发号器
 
 - 随机id
- UUID
 - SnowflakeId
 - MongodbId
 
 
 - 顺序id
 
Timestamp
UUID
UUID有128位,由32个的16进制数字组成,形式为 8-4-4-4-12 的32个字符(算上短横杠的话有36个字符)
UUID的重复性
- 版本1和2:可能会重复(因为依赖的时间戳、随机数和MAC地址可能会重复)
 - 版本3和5:同名的相同,不同名的不相同
 - 版本4:可能会重复(因为依赖的随机数可能会重复)
 
ps:当使用虚拟机和容器时MAC地址可能会重复
Snowflake
- Snowflake ID入门
 - Snowflake ID进阶
 - Snowflake ID详解
 - Snowflake ID之UidGenerator详解
 - Snowflake ID之Leaf详解
 - Snowflake ID重复问题入门
 - Snowflake ID重复问题进阶
 - Snowflake ID重复问题详解
 - Snowflake ID之如何解决时钟回拨的问题
 - Snowflake ID之UidGenerator如何解决时钟回拨的问题
 - Snowflake ID之Leaf如何解决时钟回拨的问题
 - Snowflake ID之动态生成workerId
 - Snowflake ID之感受一下性能高出587倍的全局唯一ID生成算法
 
SnowflakeId:1(符号位) + 41(时间戳) + 10(workerId) + 12(offset)
ps:workerId = 5(machineId) + 5(datacenterId)
ps:时间戳是一个偏移量不一定要从1970-1-1开始,可以从第一次上线时间开始
ps:可以按照实际需求做调整,比如增加时间戳或者偏移量的位数
- workerId生成方案
- machineId + datacenterId
 - redis自增
 
 - machineId生成方案
- hostname(简单,固定,需要注意检查是不是localhost)
 - ip(复杂,可能会变,需要注意排除localhost和虚拟机ip)
 
 - datacenterId生成方案
- redis自增
 
 
如何解决时钟回拨
- UidGenerator
- 每次启动时生成新的机器id
 - 运行时检测到时钟回拨则抛出异常
 
 - Leaf
- 运行时检测到时钟回拨则阻塞等待直到时间到达
 
 
Mysql
Redis
MongoDB
MongodbId:4byte时间戳 + 3byte机器哈希 + 2byte进程id + 3byte自增计数
SnowflakeId:1(符号位) + 41(时间戳) + 10(workerId) + 12(offset)
Docker
分布式锁
分布式事务
事务的分类
- 本地事务(ACID理论)
- 2PC
 - 3PC
 
 - 分布式事务
- 刚性事务(CAP理论、强一致性)
- 2PC(Seata-XA/AT)
 - 3PC(Seata-XA/AT)
 
 - 柔性事务(BASE理论,最终一致性)
- 补偿型
- TCC(Seata-TCC)
 - SAGA(Seata-SAGA)
 
 - 通知型
- 本地消息表
 - MQ事务消息
 - 最大努力通知
 
 
 - 补偿型
 
 - 刚性事务(CAP理论、强一致性)
 
ps:XA/AT是通用的事务协议(AT是高性能版的XA),JTA和JTS是Java的事务协议
ps:TCC和2PC的流程相似,TCC适用于业务系统,2PC适用于存储系统
ps:最大努力通知也称定期校对,是对MQ事务方案的进一步优化,它在事务主动方增加了消息校对的接口,如果事务被动方没有接收到主动方发送的消息,此时可以调用事务主动方提供的消息校对的接口主动获取没有处理完成的消息
事务的概念
- TX:应用程序与事务管理器之间的接口协议
 - XA:事务管理器与资源管理器之间的接口协议
 - AP:应用程序
 - RM:资源管理器
 - TM:事务管理器
 - 2PC:Prepare、Commit、Rollback,两阶段提交(Two-Phrase-Commit)
 - 3PC:Can、Prepare、Commit、Rollback,三阶段提交(Three-Phrase-Commit)
 - TCC:Try、Confirm、Cancel,两阶段提交(Two-Phrase-Commit)
 
ps:XA规范是X/Open组织定义的分布式事务处理(DTP,Distributed Transaction Processing)标准
事务的流程
本地消息表
本地消息表使用了两阶段提交的思想来保证本地事务和事务消息的一致性
- 事务主动方写业务表
 - 事务主动方写消息表
 - 事务主动方发送事务执行消息
 - 事务被动方消费事务执行消息
 - 事务被动方写业务表
 - 事务被动方发送事务结果消息
 - 事务主动方消费事务结果消息
 - 事务主动方更新消息表的状态
 
ps:如果事务被动方执行成功,可以发成功消息让事务主动方提交
ps:如果事务被动方执行失败,可以发失败消息让事务主动方回滚
失败时的相关处理
- 第1步和第2步失败,事务主动方直接回滚本地事务就行了
 - 其他步骤失败,事务主动方根据消息表状态重发就行了
 
MQ事务消息
MQ事务消息使用了两阶段提交的思想来保证本地事务和事务消息的一致性
- 事务主动方在事务执行前发送半消息(半消息对消费者不可见)
 - 事务主动方执行事务
 - 事务主动方在事务执行后发送事务消息
 
- 事务执行成功发送提交消息
 - 事务执行失败发送回滚消息
 
失败时的相关处理
- 第1步失败,事务主动方重发就行了
 - 第2步失败,事务主动方回滚就行了
 - 第3步失败
- MQ发起回查消息
 
- 事务主动方检查事务状态并重发就行了
 
 
事务的问题
2PC的问题
- 性能问题:参与者获取被占用的资源时会被阻塞
 - 协调问题:协调者挂掉后参与者不会释放占用的资源
 - 网络问题
- 部分执行问题:因为网络问题导致只有部分参与者收到了Commit或者Rollback请求
 - 重复执行问题:因为网络问题导致参与者重复收到了Commit或者Rollback请求
 - 空回滚问题:因为网络问题导致Prepare丢失或者Prepare晚于Rollback达到,使得还没有执行过Prepare就执行Rollback
 
 
ps:问题的关键字:性能、协调、网络
ps:协调者有超时机制,参与者没有超时机制
3PC的问题
- 网络问题
- 部分执行问题:因为网络问题导致只有部分参与者收到了提交或者回滚请求
 - 重复执行问题:因为网络问题导致参与者重复收到了提交或者回滚请求
 - 空回滚问题:因为网络问题导致Prepare丢失或者Prepare晚于Rollback达到,使得还没有执行过Prepare就执行Rollback
 
 
ps:3PC新增了can阶段来判断是否能够执行事务从而减少了事务失败时的阻塞时间
ps:3PC新增了参与者超时机制来避免协调者挂掉后参与者不会释放占用的资源的问题
TCC的问题
- 每个操作都需要支持额外的确认和取消操作
 - 每个操作都需要支持幂等
 - 网络问题
- 部分执行问题:因为网络问题导致只有部分参与者收到了Confirm或者Cancel请求
 - 重复执行问题:因为网络问题导致参与者重复收到了Confirm或者Cancel请求
 - 空回滚问题:因为网络问题导致Try丢失或者Try晚于Cancel达到,使得还没有执行过Try就执行Cancel
 
 
事务的补偿
- 回滚
 - 重试