文章目录
- CAP理论
- 分布式一致性框架
- BASE理论
- 分布式事务一致性算法
- 2PC(二阶段提交)
- 过程
- 缺点
- 3PC(三阶段提交)
- 过程
- 优点
- 分布式锁
- Mysql分布式锁
- Redis分布式锁
- 常规实现
- 存在的问题
- setnx和expire非原子性
- 超时解锁导致并发
- 无法等待锁释放
- 一致性hash算法
- 特点
- 原理
- 不平衡问题
- 虚拟节点
- 海量数据处理
- 中位数
- 分布式常见问题
CAP理论
- 一致性(Consistency): 写操作之后的读操作,必须返回该值。
- 强一致性
对于关系型数据库,要求更新的数据立即能被后续操作看到,CAP理论的一致性指这个 - 弱一致性
如果能容忍后续的部分或者全部访问不到,则是弱一致性。 - 最终一致性
如果经过一段时间后要求能访问到更新后的数据,则是最终一致性
- 可用性(Availability): 只要收到用户的请求,服务器就必须在合理的时间内给出正确的回应,不能不响应或者响应错误
- 分区容错性(Partition Tolerance): 分布式系统出现网络分区(出现多个联通分支)的时候,仍然能够对外提供服务
主从数据库
在出现分区的情况下,系统在C和A之间只能二选一
分布式一致性框架
- zookeeper:强一致性
- etcd
BASE理论
- 基本可用(Basically Available):分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用。
- 软状态(Soft State):允许系统存在中间状态,而该中间状态不会影响系统整体可用性,例如订单状态处于支付中
- 最终一致性(Eventually Consistency):系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。
分布式事务一致性算法
- 事务管理器负责协调各个节点事务的提交和回滚
2PC(二阶段提交)
过程
- 准备阶段:各个分布式节点执行自身的本地事务,写undo日志和redo日志,但是不提交事务
- 提交阶段:决定每个节点执行的事务是否需要提交,一个失败则回滚
缺点
- 同步阻塞:在准备阶段和提交阶段所有资源是被锁住的,其他第三方节点不可访问
- 单点故障:事务管理器发生故障将会导致所有参与者一直阻塞
- 数据不一致:协调者发出commit请求后,未能正确到达参与者,只有部分参与者可以commit成功
- 不确定性:当协事务管理器发送 commit 之后,并且此时只有一个参与者收到了 commit,那么当该参与者与事务管理器同时宕机之后,重新选举的事务管理器无法确定该条消息是否提交成功。
3PC(三阶段提交)
- 超时机制:解决单点故障,一段时间得不到相应则事务失败
- 在准备阶段增加一个CanCommit阶段减少同步阻塞问题
过程
- CanCommit
- 协调者向所有参与者发送消息,询问参与者是否可以执行事务提交
- 参与者向协调者返回是否可以执行事务
- PreCommit
- 发送预提交请求:协调者向各参与者发送preCommit请求,并进入prepared阶段
- 事务预提交:参与者接收到preCommit请求后,会执行事务操作,并将Undo和Redo信息记录到事务日记中
- 各参与者向协调者反馈事务执行的响应:如果各参与者都成功执行了事务操作,那么反馈给协调者Ack响应,同时等待最终指令,提交commit或者终止abort
- doCommit
- 发送提交请求:假设协调者正常工作,接收到了所有参与者的ack响应,那么它将从预提交阶段进入提交状态,并向所有参与者发送doCommit请求
- 事务提交:参与者收到doCommit请求后,正式提交事务,并在完成事务提交后释放占用的资源
- 反馈事务提交结果:参与者完成事务提交后,向协调者发送ACK信息
- 完成事务:协调者接收到所有参与者ack信息,完成事务
优点
- 降低了参与者阻塞范围,Cancomit,如果不能
- 在单点故障之后继续达成一致
分布式锁
Mysql分布式锁
- 添加数据,利用主键的唯一性
Redis分布式锁
常规实现
if (setnx(key, 1) == 1){ // 如果key不存在,返回1
expire(key, 30) // 设置key的过期时间
try {
//TODO 业务逻辑
} finally {
del(key)
}
}
存在的问题
setnx和expire非原子性
- 使用lua脚本
超时解锁导致并发
- 为获取锁的线程增加守护线程,为将要过期但未释放的锁增加有效时间。
无法等待锁释放
- 超时释放锁
一致性hash算法
key%N,key是数据的key,N是机器节点数,如果有一个机器加入或退出这个集群,则所有的数据映射都无效了
特点
- 平衡性
哈希的结果能够尽可能分布到所有的节点中去
- 单调性
新增或者删减节点时,不影响系统正常运行
- 分散性
数据应该分散地存放在分布式集群中的各个节点(节点自己可以有备份),不必每个节点都存储所有的数据。
原理
- 采用hash环实现
- 增加节点
- 删除节点
不平衡问题
虚拟节点
将1台物理服务器映射为多个虚拟服务器,放置到hash环上
海量数据处理
- hash:1.统计数量,2.分治映射
- 布隆过滤器:可以快速判断一定不存在
- bit-map:快速判断某数字存在与否
- Trie树:含有大量前缀的字符串统计数量
- 堆:查询topk
- 分治-归并整理结果:文件差分,每个文件有序,每次取每个文件中的最小值放入大数据文件内
- 桶排序:大数据求中位数
中位数
遍历一遍按第一位分两个文件,统计个数,0放入file-0,1放入file-1,确定中位数在哪个文件中
遍历一遍按第二位分两个文件,统计个数,0放入file-0,1放入file-1,确定中位数在哪个文件中
分布式常见问题
- 分布式ID
使用时间戳+MAC地址 - 计数器算法
使用redis的原子自增和过期策略 - 滑动窗口算法
- 漏桶算法
- 定时去漏桶取数据,从而限制流量
- 不能短时间内处理大量请求
- 令牌桶算法
- 以一定的速率向桶中放入令牌
- 可以短时间内处理大量请求
- 微服务设计原则
- 单一职责
- 服务自治
- 轻量通信
- 粒度进化
- 分布式session
- session同步,多台服务器间同步session
- session都加入到同一个redis集群中
- nginx根据访问IP进行定位