一、分布式锁的作用:

同一时间只允许一个用户操作,

一般情况下,我们使用分布式锁主要有两个场景:

  1. 避免不同节点重复相同的工作:比如用户执行了某个操作有可能不同节点会发送多封邮件;
  2. 避免破坏数据的正确性:如果两个节点在同一条数据上同时进行操作,可能会造成数据错误或不一致的情况出现

二、分布式锁的实现方式

  1. 基于 MySQL 中的锁:MySQL 本身有自带的悲观锁 for update 关键字,也可以自己实现悲观/乐观锁来达到目的;
  2. 基于 Zookeeper 有序节点:Zookeeper 允许临时创建有序的子节点,这样客户端获取节点列表时,就能够当前子节点列表中的序号判断是否能够获得锁;
  3. 基于 Redis 的单线程:由于 Redis 是单线程,所以命令会以串行的方式执行,并且本身提供了像 SETNX(set if not exists) 、Expire这样的指令,本身具有互斥性(因为SETNX和EXPIRE组合不是原子的,因此出现了SET key value EX 6 NX指令是原子的);

三、redis分布式锁的问题

(1)锁超时:

假设现在我们有两台平行的服务 A B,其中 A 服务在 获取锁之后 突然 挂了,那么 B 服务就永远无法获取到锁了:

如果在加锁和释放锁之间的逻辑执行得太长,以至于超出了锁的超时限制,也会出现问题。因为这时候第一个线程持有锁过期了,而临界区的逻辑还没有执行完,与此同时第二个线程就提前拥有了这把锁,导致临界区的代码不能得到严格的串行执行。因此Redis 分布式锁不要用于较长时间的任务

GC可能引发的问题:服务 A 获取了锁并设置了超时时间,但是服务 A 出现了 STW 且时间较长,导致了分布式锁进行了超时释放,在这个期间服务 B 获取到了锁,待服务 A STW 结束之后又恢复了锁,这就导致了 服务 A 和服务 B 同时获取到了锁,这个时候分布式锁就不安全了。

(2)单点和多点宕机问题对分布式锁的影响:

如果 Redis 采用单机部署模式也就是单点锁,那就意味着当 Redis 故障了,就会导致整个服务不可用。

而如果采用主从模式部署,我们想象一个这样的场景:服务 A 申请到一把锁之后,如果作为主机的 Redis 宕机了,那么 服务 B 在申请锁的时候就会从 从机那里获取到这把锁,从而导致服务AB同时获取了锁,为了解决这个问题,Redis 作者提出了一种 RedLock 红锁 的算法 (Redission 同 Jedis)

四、redLock红锁

一种基于 Redis 实现分布式锁的方式。

比原先的单节点的方法更安全。它可以保证以下特性:

  1. 安全特性:互斥访问,即永远只有一个 client 能拿到锁
  2. 避免死锁:最终 client 都可能拿到锁,不会出现死锁的情况,即使原本锁住某资源的 client crash 了或者出现了网络分区
  3. 容错性:只要大部分 Redis 节点存活就可以正常提供服务

redlock算法:

假设有5个完全独立的redis主服务器,为了获得锁,client 会进行如下操作

1.获取当前时间戳

2.client尝试顺序的使用相同的key,value申请所有redis服务的锁,在获取锁的过程中的获取时间比锁过期时间timeout短很多,是为了不要过长时间的等待已经关闭的redis服务。并且试着获取下一个redis实例。

比如:timeout为5s,设置获取锁最多用1s,所以如果一秒内无法获取锁,就放弃获取这个锁,从而尝试获取下个锁

3.当 client 在大于等于 3 个 master 上成功申请到锁的时候,会计算申请锁消耗了多少时间,这部分消耗的时间采用获得锁的当下时间戳减去第一步获得的时间戳得到,如果申请花费的时间小于timeout的时间,那么锁就真正获取到了。

4.如果成功获取锁,则锁的真正有效时间是 timeout时间减去申请锁花费的时间;比如:timeout是5s,获取所有锁用了2s,则真正锁有效时间为3s(其实应该再减去时钟漂移);

5.如果 client 申请分布式锁失败了,那么它就会在少部分申请成功锁的 master 节点上执行释放锁的操作,重置状态

6.失败重试:如果一个 client 申请锁失败了,那么它需要稍等一会再重试避免多个 client 同时申请锁的情况,另外就是如果 client 申请锁失败了它需要尽快在它曾经申请到锁的 master 上执行 unlock 操作,便于其他 client 获得这把锁,避免这些锁过期造成的时间浪费

7.崩溃恢复:如果我们的节点没有持久化机制,client 从 5 个 master 中的 3 个处获得了锁,然后其中一个重启了,这是注意 整个环境中又出现了 3 个 master 可供另一个 client 申请同一把锁! 违反了互斥性。

如果我们开启了 AOF 持久化那么情况会稍微好转一些,因为 Redis 的过期机制是语义层面实现的,所以在 server 挂了的时候时间依旧在流逝,重启之后锁状态不会受到污染。但是考虑断电之后呢,AOF部分命令没来得及刷回磁盘直接丢失了,除非我们配置刷回策略为 fsnyc = always,但这会损伤性能。

解决这个问题的方法是,当一个节点重启之后,我们规定在 max timeout期间它是不可用的(不可以被获取锁的),这样它就不会干扰原本已经申请到的锁,等到它 crash 前的那部分锁都过期了,环境不存在历史锁了,那么再把这个节点加进来正常工作。

redis相关知识记录整理相关推荐

  1. [Redis6]Redis相关知识介绍

    Redis介绍相关知识 端口6379 6379 是 "MERZ " 九宫格输入法对应的数字.Alessia Merz 是一位意大利舞女.女演员. Redis 作者 Antirez ...

  2. Redis相关漏洞记录

    不是很了解Redis数据库,粗浅学了一下Redis应该是以键值对的方式存储数据的 Redis默认端口:6379 Redis相关操作 连接远程服务器: redis-cli -h [目标IP] -p [端 ...

  3. 数据库:Redis相关知识梳理

    1.数据类型 string(字符串):最基本的k-v存储 ,适合验证码.配置信息等 list(列表):适合有序/固定的列表.比如行政区.字典表.消息队列等. set(集合):支持交集.并集.差集等操作 ...

  4. 卫星定位与导航相关知识的整理

    一.全球卫星导航系统 GNSS:Global Navigation Satellite System GPS:Global Positioning System(24颗卫星.10m) BDS:北斗系统 ...

  5. Linux 系统相关知识记录

    ==========================Linux 系统相关========================= 问题:找不到动态链接库 办法:配置动态链接地址 export LD_LIBR ...

  6. Linux服务器相关知识记录

    Linux服务器 windows远程连接linux服务器 无图形界面 包括图形界面 文件传输 服务器休眠设置 Linux桌面快捷方式的创建(Linux打开Ansys方法) Xftp远程连接出现中文乱码 ...

  7. Redis 6 学习记录

    文章目录 1. NoSQL数据库 1.1 技术发展 1.2 NoSQL数据库 2. Redis概述与安装 2.1 安装 2.2 操作 2.3 Redis相关知识 3. 常用五大数据类型 3.1 Red ...

  8. STM32 USB相关知识扫盲

    STM32 USB相关知识扫盲 目录 STM32 USB相关知识扫盲 1.基础知识 2.电气属性 2.1 数据线 2.2 USB主机是如何识别设备是高速设备/全速设备/低速设备? 3.USB设备分类 ...

  9. Redis面试题相关知识整理

    Redis面试题相关知识整理 1.Redis的应用场景 2.Redis的特点 3.Redis对各种数据类型的操作 4.Redis的持久化机制 5.Redis的缓存穿透/缓存击穿/缓存雪崩问题 6.Re ...

最新文章

  1. linux c 内存泄漏调试工具 《valgrind用户手册》 2. 使用和理解Valgrind核心
  2. 机器学习初学者公众号下载资源汇总(一)
  3. VB6.0连接MySQL数据库
  4. python使用笔记
  5. JAVA实现链表面试题
  6. pandas 第一行_用Excel表格带你学习pandas最核心的处理操作,不再害怕条件统计
  7. 托管元数据(2)——托管元数据和搜索中的精简面板
  8. 有啥不同?来看看Spring Boot 基于 JUnit 5 实现单元测试
  9. Linux TTY/PTS概述
  10. ES6学习笔记(四)-数值扩展
  11. jquery鼠标右键事件
  12. IDEA代码格式化校验
  13. Python转换图片大小格式
  14. 三容水箱液位控制系统_基于Labview软件编程的三容水箱液位控制系统
  15. [跟进]_中国银联悄然推出B2C网站-银联在线商城
  16. PHP slideup,vue+原生JavaScript实现slideDown与slideUp[简单思路]
  17. 手机怎么伪原创火山小视频 本地短视频去水印在线
  18. s饥荒服务器物品id,饥荒物品代码大全
  19. 【戒焦戒躁,can win】Linux--inode
  20. el-form表单添加自定义验证

热门文章

  1. Java核心(三)并发中的线程同步与锁
  2. Vue.js 2.x笔记:表单绑定(3)
  3. 关闭sql执行功能及找回08CMS系统管理员密码
  4. 网络学习(二十七)Windows XP 加入 Windows Server 2003 Active Directory
  5. 世界第一薄MacBook Air笔记本切菜演示(组图)
  6. 如何建立论坛的核心用户--引发的思考
  7. 4e4 Coursework decomposition
  8. Become a science founder fellowship
  9. if you want to buy something
  10. sun building in shanghai