热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

redis分布式锁实现原理_redis分布式锁实现方案解读

今天读了redis分布式锁的相关内容,刚才写了很多,结果发布的时候,出了bug,正文内容全没了,重新写一下。目

今天读了redis分布式锁的相关内容,刚才写了很多,结果发布的时候,出了bug,正文内容全没了,重新写一下。

目前redis因其优良的性能及多种数据结构的支持,已经被越来越多的公司使用,其中一些高并发场景,如抢购、秒杀、抢票等,会用到redis来实现分布式锁及减库存操作,但是,在使用过程中,可能出现一些超卖的情况,这些基本上是由于redis分布式锁实现方式及减库存操作非原子性引起的,在此分析下常见的分布式锁实现方案。

1.redis setnex实现分布式锁。

1.1 目前,redis已经支持set(key,val,ex|px,nx|xx)来保证原子性,但是在低版本(2.6.12以前),只能通过setnx和setex两条命令来实现,是非原子性操作(如果一个进程在setnx以后panic了,那这个锁就永远不能unlock了),具体可参考SET - Redis 命令参考。常见的加锁方式如下:

//10s nx加锁
set(k,v,100s,nx)
//业务逻辑
...
//解锁
unlock

1.2 这种情况下,只关心k是否已经存在,不关心val的值。但是,在高并发模式下,这种方式会出现问题。比如,秒杀时,负载极高时,可能出现进程A业务逻辑处理时间超过10s的情况,这种情况下,进程A还在处理业务逻辑时,锁已经失效了。此时进程B可以获取到锁,并处理业务,如果在处理过程中,A走到了解锁逻辑,就会把B进程的锁unlock掉。这样逐级往后,会出现套娃情况,后果无法预料。

1.3 因此做优化,来保证进程A只能unlock掉自己的锁。可以启用val,比较不同进程的val值,与set值相同,才可以unlock,此时需要保证不同进程获取到的val不一样,可以用各种开源的getuuid算法。伪代码如下:

//10s nx加锁
set(k,v,100s,nx)
//业务逻辑
...
//解锁
if(val == get(k)){unlock
}

但是这样,解锁还不是原子操作,为了保证原子操作,可以用redis的lua脚本功能,用lua脚本的原子性来保证解锁的原子性。得解。但是有一个最大的问题,它加锁时只作用在一个Redis节点上,即使Redis通过sentinel保证高可用,如果这个master节点由于某些原因发生了主从切换,那么就会出现锁丢失(主要表现情况是:redis在master加锁了,还未来得及同步到slave,发生了主从切换,导致锁丢失,这种情况下此种实现方式无解,详细参考3.redlock)。

2.redisson:Java实现的对各种redis的各种功能封装,包括分布式锁,红锁,哨兵、主从等,原子操作主要是通过lua脚本来实现的,感兴趣的同学可以去看下源码。具体功能可以参考redisson官网:https://redisson.org/。

3.redlock(红锁):这是一个大神写的,主要用于redis多实例分布式锁,其实现依赖于redis的多个无关联的实例。只要n/2+1个实例顺序加锁成功(超过设置的超时时间视为失败),并且加锁时间和

最后总结下,如果并发量不大,可以考虑1.1的方式;如果高并发,则可以考虑1.2和1.3的方案;如果对加锁有极致的要求,则可以考虑redlock。

以上。



推荐阅读
  • 2019年后蚂蚁集团与拼多多面试经验详述与深度剖析
    2019年后蚂蚁集团与拼多多面试经验详述与深度剖析 ... [详细]
  • ### 优化后的摘要本学习指南旨在帮助读者全面掌握 Bootstrap 前端框架的核心知识点与实战技巧。内容涵盖基础入门、核心功能和高级应用。第一章通过一个简单的“Hello World”示例,介绍 Bootstrap 的基本用法和快速上手方法。第二章深入探讨 Bootstrap 与 JSP 集成的细节,揭示两者结合的优势和应用场景。第三章则进一步讲解 Bootstrap 的高级特性,如响应式设计和组件定制,为开发者提供全方位的技术支持。 ... [详细]
  • 本文深入探讨了NoSQL数据库的四大主要类型:键值对存储、文档存储、列式存储和图数据库。NoSQL(Not Only SQL)是指一系列非关系型数据库系统,它们不依赖于固定模式的数据存储方式,能够灵活处理大规模、高并发的数据需求。键值对存储适用于简单的数据结构;文档存储支持复杂的数据对象;列式存储优化了大数据量的读写性能;而图数据库则擅长处理复杂的关系网络。每种类型的NoSQL数据库都有其独特的优势和应用场景,本文将详细分析它们的特点及应用实例。 ... [详细]
  • 优化后的标题:深入解析09版Jedis客户端
    深入解析09版Jedis客户端,本文将详细介绍如何在Java项目中正确配置Jedis以操作Redis。首先,确保项目的JDK版本和编译器设置正确。接着,通过Maven或Gradle导入必要的依赖项,如 `redis.clients:jedis`。此外,文章还将探讨Jedis连接池的配置与优化,以及常见问题的解决方案,帮助开发者高效使用Jedis进行Redis操作。 ... [详细]
  • V8不仅是一款著名的八缸发动机,广泛应用于道奇Charger、宾利Continental GT和BossHoss摩托车中。自2008年以来,作为Chromium项目的一部分,V8 JavaScript引擎在性能优化和技术创新方面取得了显著进展。该引擎通过先进的编译技术和高效的垃圾回收机制,显著提升了JavaScript的执行效率,为现代Web应用提供了强大的支持。持续的优化和创新使得V8在处理复杂计算和大规模数据时表现更加出色,成为众多开发者和企业的首选。 ... [详细]
  • 本文详细介绍了在 Oracle 数据库中使用 MyBatis 实现增删改查操作的方法。针对查询操作,文章解释了如何通过创建字段映射来处理数据库字段风格与 Java 对象之间的差异,确保查询结果能够正确映射到持久层对象。此外,还探讨了插入、更新和删除操作的具体实现及其最佳实践,帮助开发者高效地管理和操作 Oracle 数据库中的数据。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 本文将继续探讨 JavaScript 函数式编程的高级技巧及其实际应用。通过一个具体的寻路算法示例,我们将深入分析如何利用函数式编程的思想解决复杂问题。示例中,节点之间的连线代表路径,连线上的数字表示两点间的距离。我们将详细讲解如何通过递归和高阶函数等技术实现高效的寻路算法。 ... [详细]
  • 分享一款基于Java开发的经典贪吃蛇游戏实现
    本文介绍了一款使用Java语言开发的经典贪吃蛇游戏的实现。游戏主要由两个核心类组成:`GameFrame` 和 `GamePanel`。`GameFrame` 类负责设置游戏窗口的标题、关闭按钮以及是否允许调整窗口大小,并初始化数据模型以支持绘制操作。`GamePanel` 类则负责管理游戏中的蛇和苹果的逻辑与渲染,确保游戏的流畅运行和良好的用户体验。 ... [详细]
  • 本文详细介绍了使用 Python 进行 MySQL 和 Redis 数据库操作的实战技巧。首先,针对 MySQL 数据库,通过 `pymysql` 模块展示了如何连接和操作数据库,包括建立连接、执行查询和更新等常见操作。接着,文章深入探讨了 Redis 的基本命令和高级功能,如键值存储、列表操作和事务处理。此外,还提供了多个实际案例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 本文介绍了如何在 Windows 系统上利用 Docker 构建一个包含 NGINX、PHP、MySQL、Redis 和 Elasticsearch 的集成开发环境。通过详细的步骤说明,帮助开发者快速搭建和配置这一复杂的技术栈,提升开发效率和环境一致性。 ... [详细]
  • 本文详细介绍了如何安全地手动卸载Exchange Server 2003,以确保系统的稳定性和数据的完整性。根据微软官方支持文档(https://support.microsoft.com/kb833396/zh-cn),在进行卸载操作前,需要特别注意备份重要数据,并遵循一系列严格的步骤,以避免对现有网络环境造成不利影响。此外,文章还提供了详细的故障排除指南,帮助管理员在遇到问题时能够迅速解决,确保整个卸载过程顺利进行。 ... [详细]
  • 美团优选推荐系统架构师 L7/L8:算法与工程深度融合 ... [详细]
  • 在C语言中,定义一个包含学号、姓名和年龄的学生信息结构体,并遵循严格的命名规范。首先,初始化结构体变量的所有成员为默认值,然后将其学号设为88,姓名设为“liming”,年龄设为25。最后,在控制台上输出该结构体变量的详细信息,以验证数据的正确性。例如,使用 `typedef struct Student` 定义结构体类型。 ... [详细]
  • 基于Node.js的高性能实时消息推送系统通过集成Socket.IO和Express框架,实现了高效的高并发消息转发功能。该系统能够支持大量用户同时在线,并确保消息的实时性和可靠性,适用于需要即时通信的应用场景。 ... [详细]
author-avatar
ruigh
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有