1. 2PC
1.1 准备阶段
- 事务协调者向所有参与者节点询问是否可以执行提交操作,并开始等待各参与者节点的响应。
- 参与者节点执行询问发起为止的所有事务操作,并将Undo和Redo信息写入日志。
- 各参与者节点响应事务协调者发起的询问。如果参与者节点的事务操作实际执行成功,则它返回一个“同意”信息,否则返回“终止”信息。
1.2 提交阶段
所有参与者节点都返回同意
- 事务协调者节点向所有参与者节点发出“正式提交”的请求。
- 参与者节点正式完成操作,并释放在整个事务期间内占用的资源。
- 参与者节点向协调者节点发送“完成”信息。
- 事务协调者节点接收到所有参与者节点反馈的“完成”信息后,完成事务。
任一参与者节点返回中止
- 事务协调者节点向所有参与者节点发出“回滚操作”的请求。
- 参与者节点利用之前写入的Undo信息执行回滚,并释放在整个事务期间内占用的资源。
- 参与者节点向事务协调者节点发送“回滚完成”信息。
- 事务协调者收到所有参与者节点反馈的“回滚完成”的信息后,取消事务。
2.分布式ID
2.1 采用不同步长
2.2 滴滴号段模式
2.3 雪花算法
百度 uid-generator
通过往数据库中插入数据返回自增ID来做为机器ID。
美团 Leaf
利用zookeeper生成顺序ID。
3. 分布式锁
3.1 基于MySQL
- 利用MySQL主键唯一的特性
首先利用主键唯一规则,在争夺锁的时候下向DB写一条记录,包括锁的ID、线程标识、重入次数、创建时间,如果插入成功表示当前线程获取到了锁,如果插入失败,可以通过while循环进行阻塞等待一段时间。而对于可重入就需要对线程的表示进行比较,如果相等就进行+1。
- 基于行锁
for update
缺点:无法实现可重入,可能造成锁表现象,同时需要建立相应的索引。
3.2 基于Redis
- 方法一
setnx key value :如果key不存在,则创建并赋值
- 时间复杂度:O(1)
- 返回值:设置成功,返回1;设置失败,返回0。
expire key seconds
-
设置key的生存时间,当key过期时(生存时间为0),会被自动删除。
-
方法二
set key value [EX seconds] [PX milliseconds] [NX|XX]
- EX second :设置键的过期时间为second秒
- PX millisecond:设置键的过期时间为millisecond毫秒
- NX:只有键不存在时,才对键进行设置操作
- XX:只在键已经存在时,才对键进行设置操作
- SET操作成功完成时,返回OK,否则返回nil
4. 限流算法
4.1 令牌桶算法
是一个存放固定容量令牌的桶,按照固定速率往桶里添加令牌。
- 按照固定速率往桶中添加令牌;
- 当桶满时,新添加的令牌被丢弃或拒绝;
- 当数据包到达时,将从桶中删除n个令牌,接着数据包被发送到网络上;
- 如果桶中令牌不足,则不会删除令牌,且该数据包将被限流(丢弃或等待)。
4.2 漏桶算法
- 固定容量的漏桶,按照常量固定速率流出水滴;
- 如果桶是空的,则不需流出水滴;
- 可以以任意速率流入水滴到漏桶;
- 如果流入水滴超出了桶的容量,则流入的水滴溢出了(被丢弃),而漏桶容量是不变的。
无法应对短时间的突发流量。