Redisson文档

Redisson文档

redisson文档


:::info
redisson作为分布式锁等功能的框架,内部的所有锁机制,都是原子操作。看门狗机制保证不会出现死锁的情况
:::

1、引入依赖

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.12.0</version>
</dependency>

2、配置redisson

@Configuration
public class MyRedissonConfig {

    @Bean(destroyMethod = "shutdown")
    public RedissonClient redisson(){
//        1、创建配置
        Config config = new Config();
        config.useSingleServer().setAddress("redis://192.168.56.10:6379");
//        根据Config创建出RedissonClient
        return Redisson.create(config);
    }
}

3、lock锁机制

  • 获取一把锁,只需要锁的名字一样就是同一把锁
RLock myLock = redisson.getLock("my_lock");
  • 加锁

myLock.lock(); 阻塞式等待
1)、锁的自动续期,如果业务时间超长,运行时间自动给锁续上新的30秒。不用担心锁过期之后自动删除
2)、加锁的业务只要运行完,就不会给当前锁续期,即使不手动释放锁,也会在默认的30秒内自动删除
myLock.lock(10 , TimeUtil.SECONDS); 10秒之后自动过期,自动解锁时间一定要大于业务执行时间

  • 问题:lock.lock(10,TimeUtil.SECONDS); 在锁时间到了之后,不会自动续期

1)如果我们传递了锁的超时时间,就发送给redis执行脚本,进行占锁,默认超时时间就是我们指定的时间
2)如果我们未指定超时时间,就使用默认的 30*1000【LockWatchdogTimeout 看门狗的默认时间】;

只要占锁成功,就会启动一个定时任务【重新给锁设置过期时间,新的过期时间就是看门狗的默认时间】

internalLockLeaseTime【看门狗时间】 / 3

:::info
推荐使用myLock.lock(10 , TimeUtil.SECONDS) 自定义锁失效时间,之后手动解锁 myLock.unlock();
:::

4、读写锁

:::info
读写锁能保证一定能读到最新的数据,修改期间,写锁是排他锁(互斥锁,独享锁),读锁是一个共享锁
:::

@GetMapping("/write")
@ResponseBody
public String writeValue(){
    String s = UUID.randomUUID().toString();
    //        获取读写锁
    RReadWriteLock lock = redisson.getReadWriteLock("wr-lock");
    RLock rLock = lock.writeLock();
    try {
        rLock.lock();
        Thread.sleep(30000);
        redisTemplate.opsForValue().set("uuid", s);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        rLock.unlock();
    }
    return s;
}
@GetMapping("/read")
@ResponseBody
public String readValue(){
    //        获取读写锁
    RReadWriteLock lock = redisson.getReadWriteLock("wr-lock");
    RLock rLock = lock.readLock();
    String uuid = "";
    try {
        rLock.lock();
        uuid = redisTemplate.opsForValue().get("uuid");
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        rLock.unlock();
    }
    return uuid;
}
  • 读 + 读 :相当于无锁,并发读只会在redis中记录好当前的读锁,他们都会枷锁成功
  • 写 + 读 :等待写锁释放
  • _写 + 写 : 阻塞方式,等待写锁释放 _
  • 读 + 写 :阻塞方式,有读锁,写锁也会等待

总结:只要有写锁的存在,都必须等待

5、闭锁

:::info
只有所有要执行的业务都执行完之后,才会去执行最终业务
:::

@GetMapping("/lockDoor")
@ResponseBody
public String lockDoor(){
    RCountDownLatch lockDoor = redisson.getCountDownLatch("lockDoor");
    lockDoor.trySetCount(5);
    try {
        lockDoor.await();
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    return "锁门了";
}
@GetMapping("/gohome/{id}")
@ResponseBody
public String gohome(@PathVariable("id") Long id){
    RCountDownLatch lockDoor = redisson.getCountDownLatch("lockDoor");
    try {
        lockDoor.countDown();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "放学了"+id;
}

6、信号量

:::info
可以用来做限流操作
:::

@GetMapping("/park")
@ResponseBody
public String park(){

    RSemaphore park = redisson.getSemaphore("park");
    try {
        park.acquire();//获取一个信号
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    return "停";
}
@GetMapping("/go")
@ResponseBody
public String go(){

    RSemaphore park = redisson.getSemaphore("park");
    try {
        park.release();//获取一个信号
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "走";
}

acquire:阻塞时等待
tryAcquire:非阻塞式等待,如果获取到则返回true,否则返回false

7、缓存一致性

  • 缓存数据一致性—双写模式

在这里插入图片描述

  • 缓存数据一致性—失效模式

在这里插入图片描述

:::info
缓存数据一致性—解决方案
:::

  • 无论是双写模式还是失效模式,都会导致缓存的不一致问题。即多个实例同时更新会出事。怎么办?
    • 1、如果是用户纬度数据(订单数据、用户数据),这种并发几率非常小,不用考虑这个问题,缓存数据加 上过期时间,每隔一段时间触发读的主动更新即可
    • 2、如果是菜单,商品介绍等基础数据,也可以去使用canal订阅binlog的方式。
    • 3、缓存数据+过期时间也足够解决大部分业务对于缓存的要求。
    • 4、通过加锁保证并发读写,写写的时候按顺序排好队。读读无所谓。所以适合使用读写锁。(业务不关心 脏数据,允许临时脏数据可忽略);
  • 总结
    • 我们能放入缓存的数据本就不应该是实时性、一致性要求超高的。所以缓存数据的时候加上过期时间,保 证每天拿到当前最新数据即可。
    • 我们不应该过度设计,增加系统的复杂性
    • 遇到实时性、一致性要求高的数据,就应该查数据库,即使慢点。

canal-----解决数据一致性

在这里插入图片描述

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redisson是一个基于Redis的分布式Java对象和服务的框架。它提供了一套易于使用且功能丰富的API,能够帮助开发人员轻松地使用Redis实现分布式锁、分布式集合、分布式对象等功能。 Redisson官方文档详细介绍了Redisson框架的使用方法和相关概念。文档首先阐述了Redisson与Redis之间的关系,强调Redis作为内存数据库的特性,以及Redisson框架对Redis进行了封装和扩展,使其能够更方便地操作和管理分布式对象和服务。 文档接着介绍了Redisson的安装和配置方法,包括依赖的引入和框架的初始化过程。对于初次使用Redisson的开发人员,这个部分能够帮助他们快速上手和配置好开发环境。 接下来的部分详细介绍了Redisson提供的各种功能和API的使用方法。其中包括分布式锁、分布式集合、分布式映射、分布式队列等功能。每个功能都有详细的介绍、示例代码和最佳实践建议,开发人员只需要按照文档中的步骤和代码,就能够轻松地使用Redisson框架来实现分布式数据的存储和管理。 文档的最后一部分是关于Redisson框架的性能和扩展性的介绍。文档中提到了Redisson框架使用了高效的网络通信协议和数据结构,能够在高并发的情况下保持较好的性能和可靠性。同时,Redisson框架支持可扩展性,能够根据应用的需求进行灵活的扩展和部署。 总的来说,Redisson官方文档详细介绍了Redisson框架的使用方法和相关概念,对于想要使用Redisson的开发人员来说,是一份非常有价值的资料。无论是新手还是有经验的开发人员,在使用Redisson框架时,都可以参考这份文档,快速上手和解决问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值