分布式锁和分布式事务和分布式Session
分布式锁和分布式事务
分布式锁
基于MySQL数据库
这种方式一般采用数据库乐观锁,不推荐使用
基于redis
加锁:
setnx
命令,key
是锁的唯一标志,可以为想要加锁的资源设置对应的key
,value
暂时设置为1,即setnx(lock_ID,1)//setnx返回1,原key不存在,加锁成功;返回0,key存在,加锁失败
解锁:释放锁,采用
del
命令del(lockID)
锁超时:得到锁的线程挂掉,来不及释放锁,资源将被永久锁住,别的线程无法进入。
setnx
的key
设置一个超时时间,保证即使没有被显式释放,也要在一定时间后自动释放使用
expire(lock_ID,30)
来实现if(setnx(lock_sale_商品ID,1) == 1){expire(lock_sale_商品ID,30)try {do something ......} finally {del(lock_sale_商品ID)} }
存在的问题
setnx
和expire
两个操作是非原子的,可以使用带可选参数(超时时间)的set
来替代
set(lock_ID,1,30,NX)
del
误删除,线程A由于执行时间过长,提前被释放了锁,线程B拿到了锁,此时线程A执行完了,进行了del
操作,但删除的实际上是B线程的锁
把当前线程的ID当作set
操作中的value
,每次释放锁时进行判断,看是否是自己占有的锁
判断和删除不是原子性操作,可以使用守护线程来解决
基于zookeeper
在指定locker节点下创建临时顺序节点,释放锁时删除该节点
获取locker下所有的子节点,客户端发现自己创建的子节点序号最小,则获取到了锁
如果非最小,则找到自己的前一个节点,调用
exist()
方法,注册事件监听器如果关注的这个节点被删除,客户端的
watcher
会收到通知,再判断是否为最小,循环往复
获取分布式锁的核心算法流程
下面同个一个流程图来分析获取分布式锁的完整算法,如下:
分布式事务
两阶段提交
- 准备阶段,协调者询问参与者是否执行成功,参与者发回事务执行结果
- 提交阶段,如果每个参与者都执行成功,协调者发送通知让参与者提交事务,否则,协调者通知参与者回滚
- 问题
- 所有事务参与者等待其他参与者响应都是阻塞状态
- 协调者发生故障影响很大,第二阶段故障会造成所有参与者一直等待
- 网络异常导致协调者只发送了部分通知,导致数据不一致
补偿事务
对每个操作都要注册一个与其对应的确认和补偿操作。三个阶段
- try 主要是对业务系统做检测和资源预留
- confirm 对业务系统做确认提交,try成功,confirm必定成功
- cancel 业务执行错误,回滚时执行的业务取消,预留资源释放
本地消息表
利用本地事务保证对两个表(本地消息表和业务数据表)操作满足事务性,并使用了消息队列
- 分布式事务操作的一方完成业务数据操作后向本地消息表发送一个消息,本地事务能保证此消息一定会被写入本地消息表
- 将本地消息表中的消息转发到kafka等消息队列,转发成功则将消息从本地消息表中删除,否则继续重新转发
- 分布式事务操作另一方从消息队列中读取消息,执行操作
是一种经典的最终一致性实现方案
MQ事务消息
- prepare消息:半消息,标志该消息处于“暂时不能投递”状态,不会被consumer消费,等到服务端收到生成者对该消息的commit和rollback后,才会被正常投递或回滚
- 两阶段提交:
- 1.生产者向服务器发送prepare消息,服务端确认后回调通知生产者执行本地事务
- 2.生产者执行完本地事务,根据结果返回commit/rollback/unknown状态玛做出不同回应
- 事务状态定时回查:服务端如果收不到状态码,回定时回调检查生产者本地事务执行状态,保证最终能和本地事务状态一致
分布式session
- 粘性session
- 第一次请求时,负载均衡设置粘性session,以后每次用户请求都转发到存有session的服务器上
- session复制
- 任何一个服务器上的session发生改变(增删改),该节点会把这个 session的所有内容序列化,然后广播给所有其它节点,不管其他服务器需不需要session,以此来保证Session同步。
- session共享
- 使用分布式缓存方案比如memcached、Redis,但是要求Memcached或Redis必须是集群
- 持久化session到数据库
分布式锁和分布式事务和分布式Session相关推荐
- redis setnx 分布式锁_手写Redis分布式锁
分布式锁使用场景 现在的系统都是集群部署,每个服务都不是单节点的了.比如库存服务,可能部署到3台机器上分别命名为节点1,节点2,节点3.库存服务需要扣减库存,扣减库存肯定需要锁吧,如果使用Lock或者 ...
- 分布式锁的应用场景_分布式缓存技术Redis:高级应用(主从、事务与锁、持久化)...
安全性设置 设置客户端操作秘密 redis安装好后,默认情况下登陆客户端和使用命令操作时不需要密码的.某些情况下,为了安全起见,我们可以设置在客户端连接后进行任何操作之前都要进行密码验证.修改redi ...
- 分布式锁(一) Zookeeper分布式锁
什么是Zookeeper? Zookeeper(业界简称zk)是一种提供配置管理.分布式协同以及命名的中心化服务,这些提供的功能都是分布式系统中非常底层且必不可少的基本功能,但是如果自己实现这些功能而 ...
- Redisson分布式锁实战-1:构建分布式锁
我们现在来到Task类当中,这个方法就是V4了/*** Redisson分布式锁实现* @throws InterruptedException*/ // @Scheduled(cron=" ...
- 请列举你了解的分布式锁_终于搞懂分布式锁是什么了!
当下在互联网技术架构中,最流行的莫过于分布式架构了.为什么大家纷纷都采用分布式架构呢? 1.高效低廉,将部署在高性能机的程序分散在多个小型机中部署: 2.扩展性强,可随着业务的扩展而横向扩展系统的性能 ...
- python redis分布式锁_Python 使用 Redis 实现分布式锁
前言 随着互联网技术的不断发展,用户量的不断增加,越来越多的业务场景需要用到分布式系统.而在分布式系统中访问共享资源就需要一种互斥机制,来防止彼此之间的互相干扰,以保证一致性,这个时候就需要使用分布式 ...
- C# Redis 分布式锁 续集 (新增Mysql分布式锁[还有更多种姿势])
上个文章 <.Net Redis 实现分布式锁 >发出去之后,有很多大佬就有了自己的见解,让我获益良多,又学到了一些新姿势(知识). 上篇主要是采用了 StackExchange.Redi ...
- 分布式锁之三:Redlock实现分布式锁
之前写过一篇文章<如何在springcloud分布式系统中实现分布式锁?>,由于自己仅仅是阅读了相关的书籍,和查阅了相关的资料,就认为那样的是可行的.那篇文章实现的大概思路是用setNx命 ...
- php使用redis分布式锁,php基于redis的分布式锁实例详解
在使用分布式锁进行互斥资源访问时候,我们很多方案是采用redis的实现. 固然,redis的单节点锁在极端情况也是有问题的,假设你的业务允许偶尔的失效,使用单节点的redis锁方案就足够了,简单而且效 ...
- redis 分布式锁 看门狗_漫谈分布式锁之Redis实现
笔耕墨耘,深研术道. 01写在前面Redis是一个高性能的内存数据库,常用于数据库.缓存和消息中间件.它提供了丰富的数据结构,更适合各种业务场景:基于AP模型,Redis保证了其高可用和高性能. 本文 ...
最新文章
- 解决Http响应内容中文乱码问题
- 对模拟int3的探索
- mysql的别名可以动态么_mysql别名的使用
- csapp:无符号数可能造成的程序bug
- linux安装多版本php_Linux系统下为Nginx安装多版本PHP
- 工作流实战_16_flowable 办理任务
- vue实例方法之set方法的实现原理
- 编写python代码估算sin(x)的值
- .net环境下ckeditor与ckfinder中文文件链接乱码的问题
- 消息队列的使用场景(转载c)
- linux 压缩文件的命令总结
- 关于前端页面的meta标签的属性及其用法
- 金蝶KIS专业版本单据导入导出工具使用说明
- 2021年N1叉车司机免费试题及N1叉车司机模拟试题
- 计算机无法识别建行网盾,win7系统下建设银行二代网银盾无法被识别如何解决...
- C++、Java、JavaScript中的正则表达式
- MAC 如何隐藏dock栏上你不想看见的图标
- 添加一个pv到vg后,误删新加入的pv,报 pv * not found or rejected by a filter
- 【AI视野·今日CV 计算机视觉论文速览 第236期】Tue, 28 Sep 2021
- Beyond Compare文件比对