redis分布式锁核心实现-创新互联-成都创新互联网站建设

关于创新互联

多方位宣传企业产品与服务 突出企业形象

公司简介 公司的服务 荣誉资质 新闻动态 联系我们

redis分布式锁核心实现-创新互联

redis分布式锁核心实现
  • 分布式锁的由来
  • 特征
  • 核心实现
    • 单实例
    • Redlock实现
      • redlock由来
      • 实现步骤
      • 源码剖析

创新互联专业IDC数据服务器托管提供商,专业提供成都服务器托管,服务器租用,内蒙古服务器托管内蒙古服务器托管,成都多线服务器托管等服务器托管服务。分布式锁的由来

在我们的日常开发中,一个进程中当多线程的去竞争某一资源的时候,我们通常会用一把锁来保证只有一个线程获取到资源。如加上synchronize关键字或ReentrantLock锁等操作。

那么,如果是多个进程相互竞争一个资源,如何保证资源只会被一个操作者持有呢?

server1、server2、server3 这三个服务都要修改amount这个数据,每个服务更新的值不同,为了保证数据的正确性,三个服务都向lock server服务申请修改权限,最终server2拿到了修改权限,即server2将amount更新为2,其他服务由于没有获取到修改权限则返回更新失败。

特征

在这里插入图片描述

核心实现 单实例

我们这里直接使用Lua脚本来保证原子性,其中
NX :表示key不存在的时候,才能set成功,也即保证只有第一个客户端请求才能获得锁,而其他客户端请求只能等其释放锁,才能获取。
EX seconds :设定key的过期时间,时间单位是秒。
PX milliseconds: 设定key的过期时间,单位为毫秒

加锁

  • 使用 Setnx 命令保证互斥性。

  • 需要设置锁的过期时间,避免死锁。

  • Setnx 和设置过期时间需要保持原子性,避免在设置 Setnx 成功之后在设置过期时间客户端崩溃导致死锁。

  • 加锁的 Value 值为一个唯一标示。由于分布式任务随机数都不可靠,可以(MAC地址+JVM进程ID) 作为唯一标示。加锁成功后需要把唯一标示返回给 Client 来用进行解锁操作。
    脚本如下:

redis.call('set',key,value,'NX','PX',30000)

解锁

  • 需要拿加锁成功的唯一标示要进行解锁,从而保证加锁和解锁的是同一个客户端。

  • 解锁操作需要比较唯一标识是否相等,相等再执行删除操作。这 2 个操作可以采用 Lua 脚本方式使 2 个命令的原子性
    脚本如下:

redis.call('get',key == value then return tostring(redis.call('del', key)==1) else return 'false' end
Redlock实现 redlock由来

上面琐大的缺点就是它加锁时只作用在一个Redis节点上,即使Redis通过sentinel保证高可用,如果这个master节点由于某些原因发生了主从切换,那么就会出现锁丢失的情况:

例如,在Redis的master节点上拿到了锁,但是这个加锁的key还没有同步到slave节点,此时master故障,发生故障转移,slave节点升级为master节点,导致锁丢失。

正因为如此,Redis作者antirez基于分布式环境下提出了一种更高级的分布式锁的实现方式:Redlock。
其核心思想为:

搞多个Redis master部署,以保证它们不会同时宕掉。并且这些master节点是完全相互独立的,相互之间不存在数据同步。同时,需要确保在这多个master实例上,是与在Redis单实例,使用相同方法来获取和释放锁。

实现步骤
  • 获取当前时间,以毫秒为单位。
  • 按顺序向5个master节点请求加锁。客户端设置网络连接和响应超时时间,并且超时时间要小于锁的失效时间。(假设锁自动失效时间为10秒,则超时时间一般在5-50毫秒之间,我们就假设超时时间是50ms吧)。如果超时,跳过该master节点,尽快去尝试下一个master节点。
  • 客户端使用当前时间减去开始获取锁时间(即步骤1记录的时间),得到获取锁使用的时间。当且仅当超过一半(N/2+1,这里是5/2+1=3个节点)的Redis master节点都获得锁,并且使用的时间小于锁失效时间时,锁才算获取成功。(如上图,10s>30ms+40ms+50ms+4m0s+50ms)
  • 如果取到了锁,key的真正有效时间就变啦,需要减去获取锁所使用的时间。
  • 如果获取锁失败(没有在至少N/2+1个master实例取到锁,有或者获取锁时间已经超过了有效时间),客户端要在所有的master节点上解锁(即便有些master节点根本就没有加锁成功,也需要解锁,以防止有些漏网之鱼)。
源码剖析

参考链接: 一文搞懂 Redis 分布式锁

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


文章标题:redis分布式锁核心实现-创新互联
文章起源:http://kswsj.cn/article/gegoi.html

其他资讯