redis 分布式锁的简单使用

RedisLock——让 Redis 分布式锁变得简单

lisence jdk

1. 项目介绍

该项目主要简化了使用 redis 分布式事务所的操作,实现傻瓜式加锁,释放锁的操作,并优雅的实现了等待锁释放的操作。等待锁释放的过程主要是使用了redis的监听功能,所以在使用该项目前,要确保redis已经开启了key事件监听,即“Ex”。

  • 如何查看 redis 是否已经开启了监听功能?
    登录 redis 后,使用命令 config get notify-keyspace-events 进行查看

github地址:https://github.com/chimmhuang/redislock
码云地址:https://gitee.com/chimmhuang/redislock
欢迎 Start、Fork~

2. 快速使用

2.1 引入 maven 坐标

<dependency>
    <groupId>com.github.chimmhuang</groupId>
    <artifactId>redislock</artifactId>
    <version>1.0.2</version>
</dependency>

2.2 注册 RedisLock

  • 方式一(推荐): 在项目的启动类上添加包扫描的路径
@ComponentScan(basePackages = "com.github.chimmhuang.redislock")
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
  • 方式二:手动注册相关的 bean
@Configuration
public class RedisConfig {

    @Bean
    public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        return container;
    }

    @Bean
    public RedisListener redisListener(RedisMessageListenerContainer redisMessageListenerContainer) {
        return new RedisListener(redisMessageListenerContainer);
    }

    @Bean
    public RedisLock redisLock(RedisTemplate redisTemplate) {
        return new RedisLock(redisTemplate);
    }
}

2.3 使用

  1. 注入 redisLock
  2. 使用 redisLock.lock(key,expire) 进行加锁
  3. 使用 redisLock.unlock(key) 进行解锁

以下提供一个单元测试的案例(火车站卖票的案例)

@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisListenerTest {

    @Autowired
    private RedisLock redisLock;

    /** 100张票 */
    private static Integer count = 100;

    @Test
    public void ticketTest() throws Exception {
        TicketRunnable tr = new TicketRunnable();
        // 四个线程对应四个窗口
        Thread t1 = new Thread(tr,"窗口A");
        Thread t2 = new Thread(tr,"窗口B");
        Thread t3 = new Thread(tr,"窗口C");
        Thread t4 = new Thread(tr,"窗口D");

        t1.start();
        t2.start();
        t3.start();
        t4.start();

        Thread.currentThread().join();

    }

    public class TicketRunnable implements Runnable {
        @Override
        public void run() {
            while (count > 0) {
                redisLock.lock("ticketLock", 3L);
                if (count > 0) {
                    System.out.println(Thread.currentThread().getName() + "售出第" + (count--) + "张火车票");
                }
                redisLock.unlock("ticketLock");

                try {
                    Thread.sleep(2000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3. 参与贡献

非常欢迎你的加入!提一个 Issue 或者提交一个 Pull Request。

目前仅仅是实现了加锁解锁的简单过程,还有其他操作有待完善和测试,如:

-[ ] 在 redis 的集群环境中,需要监听每一个 redis 的 key 事件
-[ ] 在 redis 的主备模式下,可能会存在主备 redis 切换的期间,数据(key)未同步过去问题

4. 联系作者

QQ(Wechat) : 905369866
Email : chimmhuang@163.com

5. 开源协议

MIT © Chimm Huang

<think> 首先,用户查询是:“我想查找Redis分布式锁使用场景 请问Redis分布式锁使用场景”。这明确要求我提供Redis分布式锁使用场景。 系统指令要求: - 所有行内数学表达式使用$...$格式(但用户查询涉及分布式系统和Redis,不是数学主题,所以可能不需要数学表达式。我应该避免不必要的数学内容)。 - 独立公式使用$$...$$并单独成段(同样,可能不适用)。 - LaTeX语法正确(在需要时使用)。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如 [^1]。 - 回答结构清晰,帮助用户逐步解决问题,保证回答真实可靠。 - 最后,系统提到“参考站内引用”,并提供了几个引用: - 引用[1]: 讨论Redis分布式锁的基本概念和应用场景。 - 引用[2]: 提到典型应用场景、锁粒度控制、何时不适用(如强一致性要求高、高并发、网络分区)。 - 引用[3]: 讨论在分布式系统中需要分布式锁的场景。 用户说:“上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。” 但在这个模拟中,没有“上一次的问题和你的回答”。我需要基于当前查询和提供的引用来回答。 关键点: - 回答必须基于提供的引用,因为系统指定“参考站内引用”。 - 引用中提到了一些场景: - 引用[1]: 保证资源的互斥访问。 - 引用[2]: 典型应用场景如锁粒度控制;不适用场景如强一致性要求高、超高并发、网络分区频繁。 - 引用[3]: 在分布式系统中,当多个JVM进程或服务器需要互斥访问共享资源时。 我需要结构化回答: 1. **结构清晰**:逐步解释。 2. **使用中文**:全程用中文。 3. **添加引用标识**:在引用段落末尾加 [^1], [^2], [^3]。 4. **生成相关问题**:在最后添加相关问题。 步骤: 1. **介绍分布式锁**:简要解释什么是分布式锁及其在Redis中的实现。 2. **详细描述使用场景**:基于引用,列出具体场景。 - 从引用[1]: 保证资源的互斥访问。 - 从引用[2]: 锁粒度控制;不适合的场景。 - 从引用[3]: 分布式系统下的互斥访问。 例如: - 电商系统中的库存扣减。 - 防止重复提交。 - 分布式任务调度。 3. **确保真实可靠**:基于常识和引用,不要编造。 4. **添加引用**:在每个相关部分后加引用标识。 5. **生成相关问题**:在最后添加3-5个相关问题,如“如何实现Redis分布式锁?”或“Redis分布式锁的优缺点?”。 最终回答结构: - 开头:解释Redis分布式锁。 - 主体:列出使用场景,每个场景后加引用。 - 结尾:简要总结。 - 然后:§§相关问题§§,列出相关问题。 相关问题示例: 1. Redis分布式锁如何实现? 2. 在什么情况下Redis分布式锁不适用? 3. Redis分布式锁的常见问题及解决方案? 4. 如何优化Redis分布式锁的性能? 5. Redis分布式锁与其他分布式锁(如Zookeeper)的比较? 引用应用: - 当提到一个场景时,如果来自引用,就加标识。例如,“保证资源的互斥访问 [^1]”。 现在,草拟回答: - 介绍:Redis分布式锁是一种在分布式系统中实现互斥访问共享资源的机制。它通过Redis的单线程特性和原子操作来确保锁的安全性 [^1]. - 使用场景: 1. 资源互斥访问:例如,在电商系统中,防止多个用户同时购买同一件商品导致超卖 [^1] [^3]. 2. 分布式任务调度:确保定时任务在集群中只有一个节点执行 [^2] [^3]. 3. 防止重复操作:如避免用户重复提交订单 [^1]. 4. 其他场景:基于引用和常识添加。 - 不适合的场景:强一致性要求高的场景(考虑Zookeeper)、超高并发场景(超过10万QPS)、网络分区频繁的环境 [^2]. - 相关问题:生成3个问题。 确保引用正确:引用标识应与提供的引用匹配。 </think> ### Redis分布式锁使用场景 Redis分布式锁是一种在分布式系统中实现资源共享互斥访问的机制,它利用Redis的单线程模型和原子操作(如SETNX命令)来确保多个进程或节点间对共享资源的同步访问。这种锁特别适合需要高可用性和低延迟的场景,但不适用于强一致性要求极高的环境。以下是基于实际应用场景的详细解读,我会逐步解释其主要使用场景和注意事项,帮助您全面理解。 #### 1. **资源互斥访问** 在分布式系统中,当多个进程或节点需要访问共享资源(如数据库、文件或服务)时,Redis分布式锁能防止并发冲突。例如: - **电商库存扣减**:多个用户同时抢购同一商品时,锁可以确保库存更新不会超卖(即避免两个请求同时减少库存导致负库存问题)[^1] [^3]。 - **共享配置更新**:在多节点集群中,更新全局配置时,锁保证只有一个节点执行修改,防止数据不一致 [^1]。 这种场景下,锁的粒度(如key的设计)需根据业务精细控制,以避免过度阻塞 [^2]。 #### 2. **防止重复操作** 在高并发应用中,Redis分布式锁用于避免重复执行敏感操作,提升系统可靠性: - **订单提交防重**:用户频繁点击提交订单按钮时,锁可以基于用户ID或订单ID加锁,确保同一请求只处理一次,防止重复扣款或创建重复订单 [^1] [^3]。 - **定时任务调度**:在分布式定时任务(如每天凌晨的数据备份)中,锁确保集群中只有一个节点执行任务,避免多个节点重复运行造成资源浪费 [^2] [^3]。 #### 3. **分布式任务协调** 对于需要协调多个服务的应用,Redis锁提供轻量级的同步机制: - **微服务调用链控制**:在微服务架构中,当服务A调用服务B时,锁可以管理调用顺序或资源分配,防止死锁或竞争条件 [^1]。 - **限流与排队**:在高流量场景下,锁实现简单的速率限制(如每秒只允许100个请求访问API),保护后端服务不被压垮 [^2]。 #### 注意事项:何时不适用Redis分布式锁 尽管Redis分布式锁应用广泛,但在某些场景下可能不适用,需考虑替代方案(如ZooKeeper): - **强一致性要求高**:如果业务不能容忍任何锁失效(如金融交易),Redis的AP模型可能无法保证绝对一致性,建议使用CP型系统 [^2]。 - **超高并发场景**:当QPS超过10万时,Redis可能成为瓶颈,导致性能下降 [^2]。 - **网络分区频繁**:在易发生脑裂(network partition)的环境中,Redis锁可能失效,增加业务风险 [^2]。 总之,Redis分布式锁的核心价值在于其简单、高效和易扩展,适合大多数互联网应用(如电商、社交、游戏等),但在设计时应评估锁粒度和业务容忍度 [^1] [^2] [^3]。如果您有具体业务场景,我可以进一步分析优化建议。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值