mysql 排他锁 重入_分布式锁的几种实现

一、分布式锁概述

在分布式系统架构下,资源共享不再是单机下的线程竞争,而是跨JVM进程之间的而资源共享,因此JVM锁不再满足业务需求,需要引入适合分布式系统的“锁”。

二、分布式锁设计原则

排他性:被共享资源同意时间内只能被一台机器上的一个线程使用,这点和jvm锁是一个道理。

避免死锁:线程获取到锁,在执行完业务之后,一定要释放锁(包括异常情况下释放)。

高可用:获取和释放锁要保证高可用和性能。

可重入:最好是可重入锁,即当前机器的当前线程如果没有获取到锁,那么在等待一定时间后一定要保证可以再被获取到。

公平锁:不是硬性要求,指的是不同线程获取锁时最好保证几率一样。

三、分布式锁实现方式

1. 基于数据库级别的锁

乐观锁:基于CAS(compare and swap)原理,即在表中添加一个version字段,每次更新的时候以version作为条件,只能有一个线程更新成功。

悲观锁:总是假设事情发生在最坏的情况,因此每次获取数据时都会上锁,阻塞其他线程,比如行锁、表锁、读锁、写锁。mysql和oracle是通过for update来实现的

select fields from table for update

2. 基于redis的原子操作

主要通过Redis原子操作SETNX和EXPIRE来实现,因为redis是单线程机制,所以同一时刻,同一节点只允许一个线程执行某种操作,所以满足原子性。

构造一个与共享资源相关的key

调用SETNX命令获取锁,并且设置过期时间,以防死锁

释放锁

3. 基于zookeeper的互斥排他锁

zookeeper分布式锁基于zk顺序临时节点和watcher机制,推荐使用框架curator。

原理:在每一个节点下面创建子节点的时候,选择EPHEMERAL_SEQUENTIAL或者PERSISTENT_SEQUENTIAL。新的子节点后面,会加上一个次序编号。这个次序编号,是上一个生成的次序编号加一。

1460000037486531

所以,可以规定编号最小的那个节点获得锁,其他节点只要监听自己前一个节点(通过订阅比自己小的节点的删除事件),并判断自己是不是最小的那个节点就可以了。

步骤:

创建一个根节点,最好是持久节点,代表分布式锁

需要占用锁的时候,在根节点下创建临时有序节点。

判断自己是否为当前节点列表中最小子节点,如果是则获得锁,否则监听前一个子节点的变更消息。

处理业务流程,处理完成后,删除自己的子节点,释放锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值