Redis分布式锁-golang实现

分布式事务锁通常用在多台机器上运行的程序需要进行状态同步的场景下,例如转账业务、分布式的扫描限速场景等;

如果是一个进程里面的共享资源,比如一个全局变量,也就通过代码内的锁进行上锁操作

目前微服务,分布式计算等盛行,所以一个项目可能会在很多云服务器或容器(docker)上,每个进程都是系统级别的隔离,很多时候资源都是在其他机子上,这个时候如果很多进程需要更改资源,就需要涉及到锁

但是,这个锁在每个进程的代码上是无法实现的,需要借助一个第三方的服务,比如redis,ETCD等,提供一个锁的服务,每个进程就可以通过获取这个锁,从而获取对资源的操作权

1. 定义

分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。

通过以上对比可以发现单纯的使用redis自带的setNx方法在遇到多个server使用一个redis时,因没有校验机制会出现serverA加的锁被serverB释放的情况,所以setNx多用于校验单个server是否重复提交请求,而分布式锁需要参考github.com/bsm/redislock的实现

2. 原理

首先借助于redis的setnx命令来操作,setnx本身针对key赋值的时候会判断redis中是否存在这个key,如果有返回-1, 如果没有,他会直接set键值。那他跟直接set键值有啥区别? setnx是原子操作,而set不能保证原子性。

3. setnx/setex

1)有多个协程同时抢到锁,但只有一个协程拿到锁
2)有过期时间,超过过期时间锁自动释放

  • SETNX : SETNX设置 key对应的值为 string类型的 value。 如果key 已经存在,返回 0,nx 是not exist 的意思。
  • SETEX : SETEX设置key 对应的值为 string 类型的 value,并指定此键值对应的有效期

4. redislock

通过以上对比可以发现单纯的使用redis自带的setNx方法在遇到多个server使用一个redis时,因没有校验机制会出现serverA加的锁被serverB释放的情况,所以setNx多用于校验单个server是否重复提交请求,而分布式锁需要参考github.com/bsm/redislock的实现

  1. 有多个协程同时抢到锁,但只有一个协程拿到锁
  2. 有过期时间,超过过期时间锁自动释放
  3. 通过Lua脚本判断准备释放的锁中的值是否为自己设置的

5. redis分布式锁的库

赞赏

微信赞赏支付宝赞赏

发表评论

邮箱地址不会被公开。 必填项已用*标注