Redis 应用实践:读写锁进行性能优化
mhr18 2025-03-24 18:13 9 浏览 0 评论
锁优化-读写锁
public Product getProductByReadWriteLock(Long productId) {
String redisId = SystemConstants.REDIS_KEY_PREFIX + productId;
// 1. 先查redis缓存
Product product = getProductFromRedis(redisId);
if (product != null) {
return product;
}
// 加写锁
ReadWriteLock readWriteLock = redisson.getReadWriteLock(SystemConstants.LOCK_HOT_UPDATE_PREFIX + productId);
Lock writeLock = readWriteLock.writeLock();
writeLock.lock();
// 2. DCL再查redis,因为只要有一次查询数据库操作,redis就已经有缓存数据了
Product productMysql;
try {
product = getProductFromRedis(redisId);
if (product != null) {
return product;
}
// 3. 加读锁 读数据库
ReadWriteLock readWriteLock2 = redisson.getReadWriteLock(SystemConstants.LOCK_HOT_UPDATE_PREFIX + productId);
Lock readLock = readWriteLock2.readLock();
readLock.lock();
productMysql = getProductFromMysql(productId);
readLock.unlock();
} finally {
writeLock.unlock();
}
return productMysql;
}
这是一段 Java 代码,主函数为 "getProductByReadWriteLock",该函数接收一个名为 productId 的参数,用于在 Redis 数据库和 MySQL 数据库中获取 Product 对象。
当函数被调用时,首先会根据 productId 生成一个唯一的 Redis 键值,然后尝试在 Redis 缓存中获取 Product 对象。如果 Redis 缓存中存在 Product 对象,那么函数会直接返回这个对象。
如果在 Redis 缓存中找不到该 Product 对象,那么函数会使用 Redisson 库获取另一个唯一的 Redis 键值对应的写锁。写锁在这里用于保护即将进行的可能会改变数据状态的操作,确保这些操作是原子性执行的。
获取到写锁后,函数将再次尝试从 Redis 缓存中获取 Product 对象。这是因为在获取写锁的过程中,可能已经有其他的线程获取到该 Product 对象并已经更新到了 Redis 缓存中。如果此时能在 Redis 缓存中找到 Product 对象,那么函数将直直接返回这个对象,并释放已经获取的写锁。
如果在 Redis 缓存中仍然找不到 Product 对象,那么函数将使用 Redisson 库获取相同的 Redis 键值对应的读锁。读锁在这里主要用于保护即将从 MySQL 数据库中读取的 Product 数据,确保在读取数据的过程中,MySQL 数据库中的这个 Product 数据不会被其他函数写入或修改。
当获取到读锁后,函数将从 MySQL 数据库中根据 productId 读取 Product 对象,然后释放读锁,并返回从 MySQL 数据库中获取的 Product 对象。
不论在执行过程中遇到怎样的情况,函数在最后都会确保释放已经获取的锁,防止发生死锁的情况。
通过使用 Redisson 库实现的读写锁,可以优化数据在高并发环境下的读写操作,提高系统的读写效率,从而提高系统的整体性能。
优点:
- 并发性:使用读写锁,当读操作的数量大于写操作时,可以大大提高系统的并发能力。
- 缓存一致性:通过在读取数据库之前先获取写锁再进行二次Redis检查,可以保证缓存和数据库之间的数据一致性。
- 避免死锁:代码中正确地在finally块中释放了锁,能有效地防止因异常情况而导致的死锁。
缺点:
- 对锁管理的依赖性较高:如果Redis缓存或Redisson锁服务无法正常工作,会直接影响到系统的正常运行。
- 锁粒度较大: 在这个例子中,读写锁的粒度是以整个产品对象为单位,在高并发的场景下,如果对同一productId的请求非常频繁,可能会导致其他请求需要等待释放锁而造成性能瓶颈。
- 可能会引发其他问题:使用读写锁可能会引发其他问题,比如惊群现象,在写锁释放后,大量读请求同时唤醒来争抢锁,导致过大的CPU使用率。
相关推荐
- Spring Boot3 连接 Redis 竟有这么多实用方式
-
各位互联网大厂的后端开发精英们,在日常开发中,想必大家都面临过系统性能优化的挑战。当系统数据量逐渐增大、并发请求不断增多时,如何提升系统的响应速度和稳定性,成为了我们必须攻克的难题。而Redis,这...
- 隧道 ssh -L 命令总结 和 windows端口转发配置
-
摘要:隧道ssh-L命令总结和windows端口转发配置关键词:隧道、ssh-L、端口转发、网络映射整体说明最近在项目中,因为内网的安全密级比较高,只能有一台机器连接内网数据库,推送...
- 火爆BOOS直聘的13个大厂Java社招面经(5年经验)助你狂拿offer
-
火爆BOOS直聘的13个大厂Java社招面经(5年经验)助你狂拿offer综上所述,面试遇到的所有问题,整理成了一份文档,希望大家能够喜欢!!Java面试题分享(Java中高级核心知识全面解析)一、J...
- 「第五期」游服务器一二三面 秋招 米哈游
-
一面下午2点,35分钟golang内存模型golang并发模型golanggc原理过程channel用途,原理redis数据结构,底层实现跳跃表查询插入复杂度进程,线程,协程kill原理除了kil...
- RMQ——支持合并和优先级的消息队列
-
业务背景在一个项目中需要实现一个功能,商品价格发生变化时将商品价格打印在商品主图上面,那么需要在价格发生变动的时候触发合成一张带价格的图片,每一次触发合图时计算价格都是获取当前最新的价格。上游价格变化...
- Redis 中的 zset 为什么要用跳跃表,而不是B+ Tree 呢?
-
Redis中的有序集合使用的是一种叫做跳跃表(SkipList)的数据结构来实现,而不是使用B+Tree。本文将介绍为什么Redis中使用跳跃表来实现有序集合,而不是B+Tree,并且探讨跳跃表...
- 一文让你彻底搞懂 WebSocket 的原理
-
作者:木木匠转发链接:https://juejin.im/post/5c693a4f51882561fb1db0ff一、概述上一篇文章《图文深入http三次握手核心问题【思维导图】》我们分析了简单的一...
- Redis与Java整合的最佳实践
-
Redis与Java整合的最佳实践在这个数字化时代,数据处理速度决定了企业的竞争力。Redis作为一款高性能的内存数据库,以其卓越的速度和丰富的数据结构,成为Java开发者的重要伙伴。本文将带你深入了...
- Docker与Redis:轻松部署和管理你的Redis实例
-
在高速发展的云计算时代,应用程序的部署和管理变得越来越复杂。面对各种操作系统、依赖库和环境差异,开发者常常陷入“在我机器上能跑”的泥潭。然而,容器化技术的兴起,尤其是Docker的普及,彻底改变了这一...
- Java开发中的缓存策略:让程序飞得更快
-
Java开发中的缓存策略:让程序飞得更快缓存是什么?首先,让我们来聊聊什么是缓存。简单来说,缓存是一种存储机制,它将数据保存在更快速的存储介质中,以便后续使用时能够更快地访问。比如,当你打开一个网页时...
- 国庆临近,字节后端开发3+4面,终于拿到秋招第一个offer
-
字节跳动,先面了data部门,3面技术面之后hr说需要实习转正,拒绝,之后另一个部门捞起,四面技术面,已oc分享面经,希望对大家有所帮助,秋招顺利在文末分享了我为金九银十准备的备战资源库,包含了源码笔...
- “快”就一个字!Redis凭什么能让你的APP快到飞起?
-
咱们今天就来聊一个字——“快”!在这个信息爆炸、耐心越来越稀缺的时代,谁不希望自己手机里的APP点一下“嗖”就打开,刷一下“唰”就更新?谁要是敢让咱用户盯着个小圈圈干等,那简直就是在“劝退”!而说到让...
- 双十一秒杀,为何总能抢到?Redis功不可没!
-
一年一度的双十一“剁手节”,那场面,简直比春运抢票还刺激!零点的钟声一敲响,亿万个手指头在屏幕上疯狂戳戳戳,眼睛瞪得像铜铃,就为了抢到那个心心念念的半价商品、限量版宝贝。你有没有发现一个奇怪的现象?明...
- 后端开发必看!为什么说Redis是天然的幂等性?
-
你在做后端开发的时候,有没有遇到过这样的困扰:高并发场景下,同一个操作重复执行多次,导致数据混乱、业务逻辑出错?别担心,很多同行都踩过这个坑。某电商平台就曾因订单创建接口在高并发时不具备幂等性,用户多...
- 开发一个app需要哪些技术和工具
-
APP开发需要一系列技术和工具的支持,以下是对这些技术的清晰归纳和分点表示:一、前端开发技术HTML用于构建页面结构。CSS用于样式设计和布局。JavaScript用于页面交互和逻辑处理。React...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)