广告
返回顶部
首页 > 资讯 > 数据库 >如何使用Redis实现分布式锁
  • 522
分享到

如何使用Redis实现分布式锁

2024-04-02 19:04:59 522人浏览 安东尼
摘要

这篇文章将为大家详细讲解有关如何使用Redis实现分布式锁,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。加锁部分解锁部分主要原理是使用了 redis 的 s

这篇文章将为大家详细讲解有关如何使用Redis实现分布式,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

加锁部分

如何使用Redis实现分布式锁

解锁部分

如何使用Redis实现分布式锁

主要原理是使用了 redis 的 setnx 去插入一组 key-value,其中 key 要上锁的标识(在项目中是锁死用户 userId),如果上锁失败则返回 false。但是根据二段锁的思路,仔细思考会存在这么一个有趣的现象:

假设微服务 A 的某个请求对 userId = 7 的用户上锁,则微服务 A 的这个请求可以读取这个用户的信息,且可以修改其内容 ;其他模块只能读取这个用户的信息,无法修改其内容。
假设微服务 A 的当前请求对 userId = 7 的用户解锁,则所有模块可以读取这个用户的信息,且可以修改其内容
如此一来:

  • 若微服务模块 A 接收到另一个需要修改 userId = 7 的用户 的请求时,假设这个用户还在被锁状态下,这次请求可以修改它吗?(可以,解个锁就行)

  • 若微服务模块 B 接收到另一个需要修改 userId = 7 的用户 的请求时,假设这个用户还在被锁状态下,这次请求可以修改它吗?(可以,解个锁就行)

  • 若微服务模块 A 执行上锁的请求中途意外崩掉,其他用户还能修改信息吗? (可以,解个锁就行)

很明显,这三点并不是我们所希望的。那么如何实现分布式锁才是最佳实践呐?

一个好的分布式锁需要实现什么

  • 由某个模块的某次请求上锁,并且只有由这个模块的这次请求解锁(互斥,只能有一个微服务的某次请求持有锁)

  • 若上锁模块的上锁请求超时执行,则应自动解锁,并还原其所做修改(容错,就算 一个持有锁的微服务宕机也不影响最终其他模块的上锁 )

我们应该怎么做

综上所述,我们小组的分布式锁在实现模块互斥的情况下,忽略的一个重要问题便是“请求互斥”。我们只需要在加锁时,key-value 的值保存为当前请求的 requestId ,解锁时加多一次判断,是否为同一请求即可。

那么这么修改之后,我们可以高枕无忧了吗?

是的,够用了。因为我们开发环境 Redis 是统一用一台服务器上的单例,采用上述方式实现的分布式锁并没有什么问题,但在准备部署到生产环境下时,突然意识到一个问题:如果实现主从读写分离,redis 多机主从同步数据时,采用的是异步复制,也便是一个“写”操作到我们的 reids 主库之后,便马上返回成功(并不会等到同步到从库后再返回,如果这种是同步完成后再返回便是同步复制),这将会造成一个问题:

假设我们的模块 A中 id=1 的请求上锁成功后,没同步到从库前主库被我们玩坏了(宕机),则 redis 哨兵将会从从库中选择出一台新的主库,此时若模块 A 中 id=2 的请求重新请求加锁,将会是成功的。

技不如人,我们只能借助搜索引擎划水了(大雾),发现这种情况还真的有通用的解决方案:redlock。

怎么实现 Redlock 分布式安全锁

首先 redlock 是 redis 官方文档推荐的实现方式,本身并没有用到主从层面的架构,采用的是多态主库,依次去取锁的方式。假设这里有 5 台主库,整体流程大致如下:

加锁

  1. 应用层请求加锁

  2. 依次向 5 台 redis 服务器发送请求

  3. 若有超过半数的服务器返回加锁成功,则完成加锁,如果没有则自动执行解锁,并等待一段随机时间后重试。(客观原因加锁失败:网络情况不好、服务器未响应等问题, 等待一段随机时间后重试可以避开“蜂拥而进”的情况造成服务器资源占用瞬时猛增 )

  4. 如有其中任意一台服务器已经持有该锁,则加锁失败, 等待一段随机时间后重试。 (主观原因加锁失败:已经被被别人锁上了)

解锁

直接向 5 台服务器发起请求即可,无论这台服务器上是不是已经有锁。

整体思路很简单,但是实现起来仍有许多值得注意的地方。在向这 5 台服务器发送加锁请求时,由于会带上一个过期时间以保证上文所提到的“自动解锁(容错性) ”,考虑到延时等原因,这 5 台机自动解锁的时间不完全相同,因此存在一个加

锁时间差的问题,一般而言是这么解决的:

  • 在加锁之前,必须在应用层(或者把分布式锁单独封装成一个全局通用的微服务亦可)2. 记录请求加锁的时间戳 T1

  • 完成最后一台 redis 主库加锁后,记录时间戳 T2

  • 则加锁所需时间为 T1 – T2

  • 假设资源自动解锁的时间为 10 秒后,则资源真正可利用的时间为 10 – T1 + T2。若

可利用时间不符合预期,或者为负数,你懂的,重新来一遍吧。

如果你对锁的过期时间有着更加严格的把控,可以把 T1 到第一台服务器加锁成功的时间单独记录,再在最后的可用时间上加上这段时间即可得到一个更加准确的值

现在考虑另一个问题,如果恰好某次请求的锁保存在了三台服务器上,其中这三台都宕机了(怎么这么倒霉.. TAT),那此时另一个请求又来请求加锁,岂不又回到最初我们小组所面临的问题了?很遗憾的说,是的,在这种问题上官方文档给出的答案是:启用AOF持久化功能情况会得到好转 ?

关于性能方面的处理, 一般而言不止要求低延时,同时要求高吞吐量,我们可以按照官方文档的说法, 采用多路传输同时对 5 台 redis 主库进行通信以降低整体耗时,或者把 Socket 设置成非阻塞模式 (这样的好处是发送命令时并不等待返回,因此可以一次性发送全部命令再进行等待整体运行结果,虽然本人认为通常情况下如果本身网络延迟极低的情况下作用不大,等待服务器处理的时间占比会更加大)

关于如何使用Redis实现分布式锁就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

您可能感兴趣的文档:

--结束END--

本文标题: 如何使用Redis实现分布式锁

本文链接: https://www.lsjlt.com/news/55886.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 使用Redis如何实现分布式锁
    这篇文章主要介绍了使用Redis如何实现分布式锁的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇使用Redis如何实现分布式锁文章都会有所收获,下面我们一起来看看吧。 ...
    99+
    2022-10-19
  • 如何使用Redis实现分布式锁
    这篇文章将为大家详细讲解有关如何使用Redis实现分布式锁,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。加锁部分解锁部分主要原理是使用了 redis 的 s...
    99+
    2022-10-18
  • Redis如何实现分布式锁
    目录一、前言二、正文今天我们来聊一聊分布式锁的那些事。 相信大家对锁已经不陌生了,我们在多线程环境中,如果需要对同一个资源进行操作,为了避免数据不一致,我们需要在操作共享资源之前进行...
    99+
    2022-11-12
  • Redis分布式锁如何实现
    这篇文章将为大家详细讲解有关Redis分布式锁如何实现,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。什么是分布式锁?要介绍分布式锁,首先要提到与分布式锁相对应的是线程锁、...
    99+
    2022-10-18
  • Redis实现分布式锁
    单体锁存在的问题 在单体应用中,如果我们对共享数据不进行加锁操作,多线程操作共享数据时会出现数据一致性问题。 (下述实例是一个简单的下单问题:从redis中获取库存,检查库存是否够,>0才允许下单) 我们的解决办法通常是加锁。如下加单体锁...
    99+
    2023-08-16
    分布式 java jvm
  • Redis——》实现分布式锁
    推荐链接:     总结——》【Java】     总结——》【Mysql】     总结——》【Redis】     总结——》【Kafka】     总结——》【Spring】     总结—...
    99+
    2023-09-03
    redis 分布式 过期 lua
  • SpringBoot之如何使用Redis实现分布式锁
    小编给大家分享一下SpringBoot之如何使用Redis实现分布式锁,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!springboot是什么springboot一种全新的编程规范,其设计目的是用来简化新Spring应用的...
    99+
    2023-06-14
  • SpringBoot+Redis如何实现分布式锁
    这篇文章主要介绍了SpringBoot+Redis如何实现分布式锁,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。jedis的nx生成锁 如何删除锁 模拟抢...
    99+
    2023-06-16
  • Redis中如何实现分布式锁
    这篇文章给大家介绍Redis中如何实现分布式锁,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Redis要实现分布式锁,以下条件应该得到满足互斥性 在任意时刻,只有一个客户端能持有锁。不能死锁 客户端...
    99+
    2023-06-16
  • 如何使用注解方式实现 Redis 分布式锁
    目录引入 Redisson初始化 Redisson编写 Redisson 分布式锁工具类声明注解 @Lock注解解析类引入 Redisson <dependency> <groupId>org...
    99+
    2022-07-22
    注解方式实现 Redis 分布式锁 Redis 分布式锁
  • 如何使用注解方式实现 Redis 分布式锁
    目录引入 Redisson初始化 Redisson编写 Redisson 分布式锁工具类声明注解 @Lock注解解析类引入 Redisson <dependency> ...
    99+
    2022-11-13
  • PHP+Redis实现分布式锁
    目录 一、分布式锁概述 二、redis实现锁的命令 1、redis实现锁的命令 3、释放锁的步骤 三、PHP+redis分布式锁示例 四、redis集群分布式锁 一、分布式锁概述         在分布式环境下,各个线程通过对公共资...
    99+
    2023-09-15
    分布式锁
  • redis分布式锁的实现
    一、使用分布式锁要满足的几个条件:1、系统是一个分布式系统(关键是分布式,单机的可以使用ReentrantLock或者synchronized代码块来实现)2、共享资源(各个系统访问同一个资源,资源的载体可...
    99+
    2022-10-18
  • Redis Template实现分布式锁
    今天就跟大家聊聊有关Redis Template实现分布式锁,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。可靠性首先,为了确保分布式锁可用,我们至少...
    99+
    2022-10-18
  • python实现redis分布式锁
    #!/usr/bin/env python # coding=utf-8 import time import redis class RedisLock(object): def __init__(self, key): ...
    99+
    2023-01-31
    分布式 python redis
  • Redis实现分布式锁(SETNX)
    目录 1、什么是分布式锁 2、分布式锁应具备的条件         3、为什么使用分布式锁 4、SETNX介绍 5、分布式锁实现 6、效果演示 7、Redisson分布式锁详解 8、Lua脚本实现可重入分布式锁 1、什么是分布式锁  ...
    99+
    2023-10-21
    redis 分布式 java spring boot 后端
  • redis如何实现分布式共享锁
    Redis可以通过以下两种方式实现分布式共享锁:1. 使用SETNX命令:在Redis中,可以使用SETNX命令(即SET if N...
    99+
    2023-09-04
    redis
  • 详解redis如何实现分布式锁
    小编这次要给大家分享的是详解redis如何实现分布式锁,文章内容丰富,感兴趣的小伙伴可以来了解一下,希望大家阅读完这篇文章之后能够有所收获。前言系统的不断扩大,分布式锁是最基本的保障。与单机的多线程不一样的...
    99+
    2022-10-18
  • Redis中的分布式锁如何实现
    这篇文章主要介绍了Redis中的分布式锁如何实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Redis中的分布式锁如何实现文章都会有所收获,下面我们一起来看看吧。什么是分布式...
    99+
    2022-10-19
  • Redis如何实现分布式锁详解
    目录一、前言二、实现原理2.1 加锁2.2 解锁三、通过RedisTemplate实现分布式锁四、通过Redisson实现一、前言 在Java的并发编程中,我们通过锁,来避免由于竞争...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作