上节提到了,分布式锁通常应满足如下要求,互斥性、高可用、高效率、可重入、锁失效这五个基本原则。由于Redis自身“快”的特点,所以高效率可以看作满足。

下文在单机情况下与多机情况下,对利用Redis实现分布式锁做出了阐述。

单机Redis分布式锁

由于Redis本身的单线程特性,所以可以采用设置一个值的方式进行分布式锁。通常采用SETNX(set if not exist),进行设置,对资源使用完毕后,使用DEL进行删除。可以根据SETNX的返回值得到,是否成功获得锁,这一定程度上实现了互斥性,代码如下:

SETNX lock 1
...do something
DEL lock

但这时可能会存在一个问题,如果当前机器在do something的时候宕机,锁不能得到释放,导致系统死锁,所以这里需要锁失效机制,通常的锁失效,是通过设置过期时间完成的,即,

SETNX lock 1
EXPIRE lock 5
...do something
DEL lock

注意,常见面试题出现。Redis这样设置分布式锁是正确的吗?答案显然是否定的,因为 SETNX 与 EXPIRE 是两条指令,如果中间发生了宕机,同样会导致死锁。所以这里需要一条原子性的指令完成,SET指令提供了expire参数,这里利用这个参数进行完成。

SET lock 1 ex 5 nx
...do something
DEL lock

但是这样还存在问题,考虑如下情景:

1. A设置了一个锁,但是工作还没完成,锁超时释放了。

2. 此时B申请锁,由于超时释放,申请到了锁。

这导致了目前可以有A、B同时访问资源。

所以,考虑如下情形,应当在锁快失效时,更新失效时间。

但这还存在问题,存在全局时钟依赖的问题,比如Redis和客户端的时钟不一致,仍会导致问题。但目前依赖于时钟的具有自动释放锁的分布式锁都没办解决这个问题,不过由于发生概率很小,所以可以不做考虑。

关于可重入锁实现,可以通过利用Java的ThreadLocal工具,在客户端进行操作。lock时对“入锁值”+1;unlock时对"入锁值"-1,如果"入锁值"等于0,则从redis中释放锁。

多机Redis分布式锁

多机Redis分布式锁,Redis采用了RedLock对其进行实现,并在redisson中进行了实现。RedLock主要步骤如下:

  1. 取得当前时间
  2. 使用上文提到的方法依次获取N个节点的Redis锁。
  3. 如果获取到的锁的数量大于 (N/2+1)个,且获取的时间小于锁的有效时间(lock validity time)就认为获取到了一个有效的锁。锁自动释放时间就是最初的锁释放时间减去之前获取锁所消耗的时间。
  4. 如果获取锁的数量小于 (N/2+1),或者在锁的有效时间(lock validity time)内没有获取到足够的说,就认为获取锁失败。这个时候需要向所有节点发送释放锁的消息。

但Martin对这提出了质疑:

  1. 如果 Client 1 在持有锁的时候,发生了一次很长时间的 FGC 超过了锁的过期时间。锁就被释放了。
  2. 这个时候 Client 2 又获得了一把锁,提交数据。
  3. 这个时候 Client 1 从 FGC 中苏醒过来了,又一次提交数据。

此时,数据发生了错误。

并且,Martin同时指出,RedLock是一个严格依赖于全局时钟的系统。

  1. Client 1 从 A、B、D、E五个节点中,获取了 A、B、C三个节点获取到锁,我们认为它持有了锁。
  2. 这个时候,由于 B 的系统时间比别的系统走得快,B就会先于其他两个节点优先释放锁。
  3. Clinet 2 可以从 B、D、E三个节点获取到锁。在整个分布式系统就造成 两个 Client 同时持有锁了。

所以,可以看出,Redis适用于实现高可用的分布式锁。但是对于需要在保证可用性的同时,数据正确性也需要严格保证时,并不适用于实现分布式锁。

[Re:从零开始的分布式] 0.x——Reids实现分布式锁的更多相关文章

  1. SpringBoot开发案例从0到1构建分布式秒杀系统

    前言 ​最近,被推送了不少秒杀架构的文章,忙里偷闲自己也总结了一下互联网平台秒杀架构设计,当然也借鉴了不少同学的思路.俗话说,脱离案例讲架构都是耍流氓,最终使用SpringBoot模拟实现了部分秒杀场 ...

  2. hadoop 0.20.2伪分布式安装详解

    adoop 0.20.2伪分布式安装详解 hadoop有三种运行模式: 伪分布式不需要安装虚拟机,在同一台机器上同时启动5个进程,模拟分布式. 完全分布式至少有3个节点,其中一个做master,运行名 ...

  3. 从零开始搭建Vue2.0项目(一)之快速开始

    从零开始搭建Vue2.0项目(一)之项目快速开始 前言 该样板适用于大型,严肃的项目,并假定您对Webpack和有所了解vue-loader.确保还阅读vue-loader的文档,了解常见的工作流程配 ...

  4. 分布式改造剧集2---DIY分布式锁

    前言: ​ 好了,终于又开始播放分布式改造剧集了.前面一集中(http://www.cnblogs.com/Kidezyq/p/8748961.html)我们DIY了一个Hessian转发实现,最后我 ...

  5. Zookeeper系列二:分布式架构详解、分布式技术详解、分布式事务

    一.分布式架构详解 1.分布式发展历程 1.1 单点集中式 特点:App.DB.FileServer都部署在一台机器上.并且访问请求量较少 1.2  应用服务和数据服务拆分  特点:App.DB.Fi ...

  6. 搞懂分布式技术3:初探分布式协调服务zookeeper

    搞懂分布式技术3:初探分布式协调服务zookeeper 1.Zookeepr是什么 Zookeeper是一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它实现诸如数据发布/订阅,负载均衡, ...

  7. 分布式事务(4)---RocketMQ实现分布式事务项目

    RocketMQ实现分布式事务 有关RocketMQ实现分布式事务前面写了一篇博客 1.RocketMQ实现分布式事务原理 下面就这个项目做个整体简单介绍,并在文字最下方附上项目Github地址. 一 ...

  8. 冰河开源了全网首个完全开源的分布式全局有序序列号(分布式ID)框架!!

    写在前面 mykit-serial框架的设计参考了李艳鹏大佬开源的vesta框架,并彻底重构了vesta框架,借鉴了雪花算法(SnowFlake)的思想,并在此基础上进行了全面升级和优化.支持嵌入式( ...

  9. [源码解析] PyTorch 分布式(17) --- 结合DDP和分布式 RPC 框架

    [源码解析] PyTorch 分布式(17) --- 结合DDP和分布式 RPC 框架 目录 [源码解析] PyTorch 分布式(17) --- 结合DDP和分布式 RPC 框架 0x00 摘要 0 ...

随机推荐

  1. MyBatis 实用篇(一)入门

    MyBatis 实用篇(一)入门 MyBatis(http://www.mybatis.org/mybatis-3/zh/index.html) 是一款优秀的持久层框架,它支持定制化 SQL.存储过程 ...

  2. 常见的C语言内存错误及对策(转)

    http://see.xidian.edu.cn/cpp/html/483.html 一.指针没有指向一块合法的内存 定义了指针变量,但是没有为指针分配内存,即指针没有指向一块合法的内存.浅显的例子就 ...

  3. 如何在Github上删除项目及某个文件

    在Github上删除项目 在GitHub仓库中找到已经建立好的某个仓库,本篇文章以我的myBookCodes仓库为例,在建立的myBookCodes仓库中首先找到settings选项,如图所示: 将页 ...

  4. HDU1301&&POJ1251 Jungle Roads 2017-04-12 23:27 40人阅读 评论(0) 收藏

    Jungle Roads Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 25993   Accepted: 12181 De ...

  5. MVP社区巡讲 12月5日北京站| 12月12日上海站

    2015年底的社区巡讲Powered MVP Roadshow正式启动啦!12月5日周六下午北京场,12月12日周六下午上海场. 欢迎各位邀请您的同事朋友来参加MVP的社区活动,也邀请您发送活动信息( ...

  6. MYC编译器源码分析之程序入口

    前文.NET框架源码解读之MYC编译器讲了MyC编译器的架构,整个编译器是用C#语言写的,上图列出了MyC编译器编译一个C源文件的过程,编译主路径如下: 首先是入口Main函数用来解析命令行参数,读取 ...

  7. 面向对象SOLID设计原则之Open-Closed原则

    首先,我们看下开放-封闭原则(Open-Closed Principle,简称OCP)的概念: 是指软件实体(类.模块.函数等)应该可以扩展,但是不可修改. 任何新功能(functionality)应 ...

  8. FastDFS 安装与使用

    FastDFS 安装与使用 1. 什么是 FastDFS FastDFS是一个开源的高性能分布式文件系统(DFS). 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡的设计. Fa ...

  9. 洛谷P3964 [TJOI2013]松鼠聚会(坐标系变换)

    题面 传送门 题解 对于两个点\((x_i,y_i)\)和\(x_j,y_j\),我们定义它们之间的曼哈顿距离为 \[|x_i-x_j|+|y_i-y_j|\] 定义它们的切比雪夫距离为 \[\max ...

  10. P4211[BZOJ 3626] [LNOI2014]LCA

    题目描述 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1. 设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先. 有q次询问,每 ...