上节提到了,分布式锁通常应满足如下要求,互斥性、高可用、高效率、可重入、锁失效这五个基本原则。由于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. QQ互联

    [移动应用接入概述] QQ互联开放平台为第三方移动应用提供了丰富的API.第三方移动应用接入QQ互联开放平台后,即可通过调用平台提供的API实现用户使用QQ账号登录移动应用功能,且可以获取到腾讯QQ用 ...

  2. centos环境下输入命令不能有中文那么我怎么插入中文数据到数据库

    centos环境下输入命令不能有中文那么我怎么插入中文数据到数据库 如下图: 首先查看是否安装了中文语言支持组件 yum grouplist 没有的话安装 yum install Chinese Su ...

  3. 数据结构(c语言版)文摘

    第一章  绪论 数据结构:是一门研究非数值计算的程序设计问题中计算机的操作对象以及它们之间的关系和操作等的学科. 数据:是对客观事物的符号表示,在计算机科学中是指所有能输入到计算机中并被计算机程序处理 ...

  4. HBase的FlushLargeStoresPolicy多例族支持

    众所周知,HBase的一个例族flush时,会导致所有例族都跟着被flush.在HBase-0.94的官方说明(http://hbase.apache.org/0.94/book/number.of. ...

  5. 4、Docker的安装

      docker官方安装文档 Mac上安装Docker   Install Docker for Mac | Docker Documentation Windows安装Docker   Instal ...

  6. OA与ERP集成 可行?

    [正文] 近些年来,当谈论到企业信息化的时候,ERP都成为一个热门话题,ERP的出现似乎给企业带来了一个翻天覆地的变化,而且也成为企业实现信息化的"新宠儿".然而OA也曾经是企业信 ...

  7. C#基础入门 六

    C#基础入门 六 静态类进阶 静态构造方法 用于初始化任何静态数据,或用于执行仅需执行一次的特定操作,在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数,静态构造方法是无参数的. publ ...

  8. postgres数据库参数配置说明介绍

    访问 1. listen_addresses 监听访问地址 2. port 监听端口 3. max_connections 最大连接数 4. 性能 1. shared_buffers PostgreS ...

  9. Python 爬虫入门实例(爬取小米应用商店的top应用apk)

    一,爬虫是什么? 爬虫就是获取网络上各种资源,数据的一种工具.具体的可以自行百度. 二,如何写简单爬虫 1,获取网页内容 可以通过 Python(3.x) 自带的 urllib,来实现网页内容的下载. ...

  10. elasticsearch不能使用root启动问题解决

    问题: es安装好之后,使用root启动会报错:can not run elasticsearch as root [root@iZbp1bb2egi7w0ueys548pZ bin]# ./elas ...