vlambda博客
学习文章列表

分布式锁与分布式事务

内容根据奈学教育百万架构课整理而成。


分布式锁

本质是把共享资源串行化,把并行处理转成串行处理。

 

CAP原则

这三个要素最多只能同时实现两点,不能三者兼顾,但是可以平衡,并不是完全抛弃另一个

Consistency、 Availability  、 Partition tolerance

强一致   、可用性、分区容忍

 

常见工具

redis   AP模型

分布式锁 CP模型  etcd、zk

 

设计与实践

我在给某个晚会线上互动发奖品时,面临30w/QPS,数据库达不到这个速度,使用codis来计数,奖品数量记录在30 key中,按照用户id%30,尽量控制在每个key1w的qps。有些 key 发完奖品,有些 key 还有奖品。

在并发高的情况下允许这种情况发生,如何设计最终要看业务容忍度。


分布式事务

本质是拆成多个可执行的本地事务


刚性分布式事务


2pc 两阶段提交

             

3pc 三阶段提交

              


柔性分布式事务


1:TCC 模型

try           完成业务检查锁定需要的资源

confirm   执行业务,不再做业务检查

cancel     释放try阶段锁定的资源


2:Saga 模型 

2.1:串行操作,每个事务都有执行模块和补偿模块

2.2:业务层加锁,冻结资源

2.3:如果任何一个子事务失败,都要向后恢复进行补偿


3:异步消息

3.1:业务数据与msg同时写到DB中,放到一个本地事务中提交,确保消息一定被发出

3.2:当多个客户端从表中取msg时要确保只有一个客户端能拿到数据,需要用到分布式锁

 

4:最后解决方案

4.1:写错误日志

4.2:报警

4.3:人工介入


思考题

第一题:分布式锁续租时候,GC发生,导致ETCD中锁过期,续租失败。如何解决该问题?

1:增加默认的过期时间,超过一次FGC最大时间

2:G1  -XX:MaxGCPauseMillis=500  每次最长500毫秒

第二题:SAGA模式下,如果事务有3步,最后一步失败,同时没有写入TDB的状态表,这个时候补偿只会补偿第一个事务操作,第二步不会补偿,这种CASE怎么解决?

第一次往TM写的时候,标记好这次事务有几步,假如有3步,如果该事务的最大数步数是2,说明有一个子事务没写入。

 

知识点

etcd

https://etcd.io/


zab 一致性算法

https://www.jianshu.com/p/2bceacd60b8a


raft 算法

 https://www.jianshu.com/p/8e4bbe7e276c


4种隔离性

数据库事务的隔离级别有4个,由低到高依次为Read uncommitted 、Read committed 、Repeatable read 、Serializable ,这四个级别可以逐个解决脏读 、不可重复读 、幻读 这几类问题。


RU(读未提交,脏读)

脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据

 

RC(读提交,不可重复读)

是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(即不能读到相同的数据内容)

 

RR(重复读,幻读)

是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好像发生了幻觉一样。

 

SZ(序列化)

最高的事务隔离级别,同时代价也花费最高,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻读。



脏读

不可重复读

幻读

Read uncommitted

Read committed

×

Repeatable read

×

×

Serializable

×

×

×


参考 

事务隔离级别

https://blog.csdn.net/JIESA/article/details/51317164

saga论文翻译

https://github.com/mltds/sagas-report