博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
缓存篇-Redisson的使用
阅读量:4079 次
发布时间:2019-05-25

本文共 2680 字,大约阅读时间需要 8 分钟。

文章目录


前言

使用redisson进行redis客户端操作


一、Redisson是什么?

Redisson是一个在Redis的基础上实现的Java驻内存数据网络(In-Memory Data Grid)。不仅提供了一些列的分布式java常用对象,还提供了许多分布式服务。

Redission提供了Redis最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离,集中精力在业务处理上。

二、使用Redisson

1.引入pom依赖

org.redisson
redisson
3.13.4

2.配置注入对象

@Configurationpublic class MyRedisConfig {
@Value("${spring.redis.host}") private String redisIp; @Value("${spring.redis.port}") private String redisPort; //注入RedissonClient @Bean(destroyMethod = "shutdown") RedissonClient redisson(){
//编写配置 Config config = new Config(); //单节点模式 config.useSingleServer().setAddress("redis://"+redisIp +":"+redisPort); return Redisson.create(config); }}

三、使用Redisson实现可重入锁(Reentrant Lock)

1.原因

如果A调用B。A、B都需要同一把锁,此时使用可重入锁(Reetrant Lock)就能实现可重入,A调用B。否则如果是不可重入,调用B的前提是A释放锁,A释放锁的前提是调用B,此时就形成死锁。

2.redisson使用

@ResponseBody@RequestMapping("/hello")public String hello(){
//获取一把锁 只要锁的名字一样就说是同一把锁 RLock lock = redisson.getLock("my-lock"); lock.lock(); try {
System.out.println("走业务代码"); }finally {
lock.unlock(); } return "hello";}

3.redisson看门狗机制

在这里插入图片描述

  • 锁的续期:如果没有锁的续期,存储分布式锁的redisson节点宕机,正好这个锁处于锁住状态时,这个锁就处于死锁状态。为了避免这种情况,redisson内部提供了一种监控锁的看门狗机制。
  • 看门狗的作用:在redisson实例被关闭之前,不断延长锁的有效时间。默认情况看门狗检查锁的时间是30秒。

4.redisson看门狗源码分析

在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 如果传递了锁的超时时间,就执行脚本,进行占锁;
  • 如果没传递锁时间,使用看门狗的时间,占锁。如果返回占锁成功future,调用future.onComplete();
    没异常的话调用scheduleExpirationRenewal(threadId);
    重新设置过期时间,定时任务;

看门狗的原理是定时任务:重新给锁设置过期时间,新的过期时间就是看门狗的默认时间;锁时间/3是定时任务周期;

四、使用Redisson实现读写锁(ReadWrite Lock)

分布式可重入读写锁允许同时又多个读锁和写锁处于加锁状态。

在这里插入图片描述
读时处于无锁状态。

五、使用Redisson实现信号量(Semaphore)

@GetMapping("/park")@ResponseBodypublic String park() {
RSemaphore park = redisson.getSemaphore("park"); try {
park.acquire(2); } catch (InterruptedException e) {
e.printStackTrace(); } return "park";}@GetMapping("/go")@ResponseBodypublic String go() {
RSemaphore park = redisson.getSemaphore("park"); park.release(2); return "go";}

信号量可以做限流等应用

六、使用Redisson实现分布式闭锁(CountDownLatch)

在这里插入图片描述

七、缓存和数据库一致性解决方案

  • 双写模式。写完数据库后,写缓存。
  • 失效模式。写完数据库后,删缓存。

1.出现的问题

双写模式:

并发时,2号线程进入,写完DB后写缓存。而此时1号线程还没有写缓存,造成短时间内缓存有脏数据。
在这里插入图片描述
失效模式:
并发时,
1号线程先写数据库,删缓存,
2号线程此时依然还在写数据库,
但是3号线程读缓存发现没有缓存,此时去读取数据库,读数据库完成之后,2号线程才写完
在3号线程写缓存之前,2号线程写完数据库,也删完了缓存,
此时3号线程更新缓存。但是更新的依然是1号线程写的数据,2号线程写的数据没有加入到缓存。
在这里插入图片描述

2.解决方案

  • 如果是用户纬度数据(订单数据、用户数据),这种并发几率非常小,不用考虑这个问题,缓存数据加上过期时间,每隔一段时间触发读的主动更新即可。

  • 如果是菜单,商品介绍等基础数据,也可以去使用canal订阅binlog的方式

    缓存数据+过期时间也足够解决大部分业务对于缓存的要求。
    在这里插入图片描述

  • 通过加锁保证并发读写,写写的时候按顺序排好队。读读无所谓。所以适合使用读写锁。(业务不关心脏数据,允许临时脏数据可忽略);

3.总结

  • 我们能放入缓存的数据本就不应该是实时性、一致性要求超高的。所以缓存数据的时候加上过期时间,保证每天拿到当前最新数据即可。

  • 我们不应该过度设计,增加系统的复杂性

  • 遇到实时性、一致性要求高的数据,就应该查数据库,即使慢点。

转载地址:http://vexni.baihongyu.com/

你可能感兴趣的文章
Android 解决TextView设置文本和富文本SpannableString自动换行留空白问题
查看>>
Android开发中Button按钮绑定监听器的方式完全解析
查看>>
Android自定义View实现商品评价星星评分控件
查看>>
postgresql监控工具pgstatspack的安装及使用
查看>>
postgresql查看表的和索引的情况,判断是否膨胀
查看>>
postgresql中根据oid和filenode去找表的物理文件的位置
查看>>
postgresql减少wal日志生成量的方法
查看>>
swift中单例的创建及销毁
查看>>
获取App Store中App的ipa包
查看>>
iOS 关于pods-frameworks.sh:permission denied报错的解决
查看>>
设置tabbaritem的title的颜色及按钮图片
查看>>
动态设置label的高度
查看>>
图片压缩
查看>>
检测缓存文件是否超时
查看>>
十进制字符串转十六进制字符串
查看>>
属性字符串(富文本)的使用
查看>>
cell上label的背景颜色在选中状态下改变的解决办法
查看>>
GPS定位
查看>>
地图、显示用户位置、大头针
查看>>
自定义大头针
查看>>