分布式锁应用方案

    最近在研究锁,来谈谈这部分的理解。

    首先,我们在使用锁时,要明确,为什么我们要使用锁?大概有三点:

    1.多任务的环境中才需要?这个多任务可以指多线程或者多进程。

    2.任务都需要对同一共享资源进行写操作时。对共享资源多线程进行修改时会引发并发安全问题。

    3.对资源的访问都是互斥的。

    当一个线程或者进行在对一共享资源进行操作时,其他线程或者进程都不可以对这个资源进行操作,知道该线程或者进程完成其操作,其他线程或者进程才能对该资源进行操作,而其他线程或者进程又处于等待状态。

分布式锁方案目前主流的大概有三种

1.利用mysql的实现方案

   实现思路:利用数据库自身提供的锁机制实现,要求数据库支持行级锁

2.利用redis的实现方案

  实现思路:使用缓存的CAS机制实现,保证对缓存操作序列的原子性

扫描二维码关注公众号,回复: 24186 查看本文章

3.利用zk的实现方案

  基于zk的节点特点以及watch机制实现

今天我们主要介绍下基于redis的分布式锁。

Redis是一个开源,内存存储的数据结构服务器。可用作数据库。高速缓存和消息队列代理。采用单线程单进程模型,并发能力强大,是目前互联网架构中主流的分布式架构工具。

关于redis分布式锁的基础知识

  • 缓存有效期

    redis的数据,不一定都是持久话的;给定key设置的生存时间,当key过期时,它会自动删除。

  • SETNX命令

    SETNX key value ,将key的值设为value,当且仅当key不存在。若给定的key已经存在,则SETNX不做任何动作。

    SETNX是【SET IF NOT EXISTS】如果不存在,则SET的简称

  • lua脚本

    轻量小巧的脚本语言,用于支持redis操作序列的原子性;

redis加解锁的正确姿势

  • 加锁

通过setnx想特定的key写入一个随机值,并设置失效时间,写值成功及加锁成功

注意点:必须设置一个失效时间                                           ------>避免死锁

              加锁时,每个节点产生一个随机字符串                   ------>避免锁误删

              写入随机值与失效时间必须是同时的                       ------>保证加锁是原子性。

SET key value NX PX 30000

  • 解锁

匹配随机值,删除redis上的特点key数据,要保证获取数据、判断一致、删除数据三个操作是原子的。

执行如下lua脚本:

if  redis.call("get",KEY[1])==ARGV[1]then

    return redis.call("del",KEYS[1])

else

    return 0;

end

猜你喜欢

转载自blog.csdn.net/paul_kk/article/details/79960691