当前位置: 首页 > news >正文

Redis专题

前言

Redis的各种思想跟机组Cache和操作系统对进程的管理非常类似!

一:看到你的简历上写了你的项目里面用到了redis,为啥用redis?

因为传统的关系型数据库如Mysql,已经不能适用所有的场景,比如秒杀的库存扣减,APP首页的访问流量高峰等,都很容易把数据库打崩,所以引入了缓存中间件,redis。

Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库;跟机组内存中的cache很相似。

集群:复制模式,每个机器做同一件事

分布式:每台机器分工合作,做的不是同一件事。

二、Redis数据类型

字符串类型String

哈希类型hash

列表类型

集合类型

有序集合类型

三:Redis的使用

1:下载软件

2:Spring-data-redis:提供了通过简单配置访问redis服务,对redis底层开发包jedis进行了高度封装,RedisTemplate类提供了redis各种操作。

     redisTemplate.opsForValue().set("name", "gao1");

    redisTemplate.opsForList().rightPush("nameList1", "刘备");

    redisTemplate.opsForHash().put("nameHash", "c", "八戒");

四、Redis常见问题

1:缓存穿透:恶意请求或者频繁查询一个不存在的数据,导致每次请求都要访问数据库。

解决:缓存空对象,并设置合适的过期时间。

2:缓存击穿:在高并发的情况下,一个热点数据的缓存过期或被删除,恰好有大量的请求同时访问该数据,导致无法从缓存中获取数据,从而直接访问数据库。

解决:互斥锁;单机环境用synchronized,集群环境则使用分布式锁(redis的setnx,Redisson)

3:缓存雪崩:在同一时段大量的缓存Key同时失效或者Redis服务宕机,导致大量请求到达数据库。(与缓存击穿的区别,雪崩是很多key,击穿是某一个key缓存)

解决:合理设置缓存过期时间,给不同的key的·TTL添加随机值;建立redis集群

缓存预热:缓存预热是指在系统启动或高峰期之前,提前将一些热点数据加载到缓存中,以减少后续请求对数据库的访问压力,提高系统的性能和响应速度

五、缓存击穿问题解决

分布式环境下解决:使用 Redisson 会更加合适。

1:引入依赖;配置文件  

 //1、获取一把锁,只要锁的名字一样,就是同一把锁RLock lock = redissonClient.getLock("my-lock");//2、加锁  阻塞式等待(没有获得锁的线程都要等待)。默认加的锁都是30s,lockWatchdogTimeout = 30 * 1000 【看门狗默认时间】lock.lock();//1)、锁的自动续期,如果业务超长,运行期间自动续期,不用担心业务时间长,锁自动过期被删掉//只要占锁成功,就会启动一个定时任务【重新给锁设置过期时间,新的过期时间就是看门狗的默认时间】,每隔10秒都会自动的再次续期,续成30秒// internalLockLeaseTime 【看门狗时间】 / 3, 10s//2)、加锁的业务只要运行完成,就不会给当前锁续期,即使不手动解锁,锁默认会在30s内自动过期,不会产生死锁问题try {System.out.println("加锁成功,执行业务..." + Thread.currentThread().getId());try { TimeUnit.SECONDS.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); }} finally {//3、解锁  假设解锁代码没有运行,Redisson会不会出现死锁System.out.println("释放锁..." + Thread.currentThread().getId());lock.unlock();}return "hello";
}

六、redis与数据库不一致问题

失效模式:修改数据库后,删除缓存后面再重新建立缓存。

双写模式:修改数据库后,修改缓存。

七、SpringCache简化缓存开发

springcache提供了一些核心概念和注解来管理缓存。

    Cache Manager  :是一个缓存的抽象接口。

    Cache:基本操作单元,定义了常见的缓存操作,例如get,put,evict(删除)

   缓存注解:

@Cacheable:触发将数据放入缓存的操作。

@CacheEvict:触发将数据从缓存删除的操作。失效模式

@CachePut:不影响方法执行更新缓存。双写模式。

// value:分组,区分不同模块的缓存
//@Cacheable(value = "product", key = "'selectById:' + #id")
@Cacheable(value = "product", key = "#root.methodName + ':' + #id")
@Override
public Product selectById(Long id) {return productMapper.selectById(id);
}
//加锁解决缓存击穿问题:sync = true
//@Cacheable(value = "product", key = "'selectById'")
//多个参数这种方式用“,”分割就不用字符串拼接了, key = "{#root.methodName, #id, #name}"
@Cacheable(value = "product", key = "#root.methodName + ':' + #id", sync = true)
@Override
public Product selectById(Long id) {return productMapper.selectById(id);
}//@CacheEvict(value = "product", allEntries = true) //删除分区中所有数据
@CacheEvict(value = "product", key = "'selectById:' + #product.id")
@Override
public void update(Product product) {productMapper.updateById(product);
}

八、Redis持久化机制

1:RDB:Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。

简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。

2:AOF:Append Only File(追加文件)

Redis处理的每一个写命令都会记录在AOF文件,可以看做是命令日志文件(不记录读命令)。

AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF

AOF重写

比如我们有个计数的服务,有很多自增的操作,比如有一个key自增到1个亿,对AOF文件来说就是一亿次incr。AOF重写就只用记1条记录。

九、Redis过期数据删除策略

​​​​​​​惰性删除 

只会在取出key的时候才对数据进行过期检查,如果过期,我们就删掉它,反之返回该key。

优点 :对CPU友好,只会在使用该key时才会进行过期检查,对于很多用不到的key不用浪费时间进行过期检查

缺点 :对内存不友好,如果一个key已经过期,但是一直没有使用,那么该key就会一直存在内存中,内存永远不会释放

​​​​​​​定期删除 

每隔一段时间抽取一批 key进行检查,删除里面过期的key。

优点:可以通过限制删除操作执行的时长和频率来减少删除操作对 CPU 的影响。也能有效释放过期键占用的内存。

缺点:难以确定删除操作执行的时长和频率。

Redis的过期删除策略:惰性删除 + 定期删除两种策略进行配合使用

十、Redis数据淘汰策略(和操作系统的进程管理类似)

当Redis中的内存不够用时,此时在向Redis中添加新的key,那么Redis就会按照某一种规则将内存中的数据删除掉,这种数据的删除规则被称之为内存的淘汰策略。

Redis支持8种不同策略来选择要删除的key:

noeviction:当内存不足时,Redis 不会淘汰任何数据,而是直接返回错误信息。这是默认的淘汰策略。

allkeys-lru: 对全体key,基于LRU算法进行淘汰

allkeys-lfu: 对全体key,基于LFU算法进行淘汰

allkeys-random:对全体key ,随机进行淘汰。

volatile-lru: 对设置了TTL的key,基于LRU算法进行淘汰

volatile-lfu: 对设置了TTL的key,基于LFU算法进行淘汰

volatile-random:对设置了TTL的key ,随机进行淘汰。

volatile-ttl: 对设置了TTL的key,比较key的剩余TTL值,TTL越小越先被淘汰


http://www.mrgr.cn/news/99347.html

相关文章:

  • [密码学基础]GMT 0002-2012 SM4分组密码算法 技术规范深度解析
  • NLP高频面试题(四十九)——大模型RAG常见面试题解析
  • [安全实战]逆向工程核心名词详解
  • Three.js 场景编辑器 (Vue3 + TypeScript 实现)
  • HTML 初识
  • # 手写数字识别:使用PyTorch构建MNIST分类器
  • Deepseek输出的内容如何直接转化为word文件?
  • [密码学基础]GM/T 0018-2023 密码设备应用接口规范深度解析:技术革新与开发者实践
  • 论文阅读:2025 arxiv AI Alignment: A Comprehensive Survey
  • c++:智能指针
  • 【学习笔记】Py网络爬虫学习记录(更新中)
  • AI助理iOS开发:Copilot for Xcode 下载与安装全指南
  • 力扣第446场周赛
  • 在kali中安装AntSword(蚁剑)
  • 【mysql】mysql疑难问题:实际场景解释什么是排它锁 当前读 快照读
  • 【C/C++】深入理解指针(二)
  • 使用 Flutter 遇坑小计
  • 获取电脑信息(登录电脑的进程、C盘文件信息、浏览器信息、IP)
  • 常见的页面报错
  • 【前端Skill】点击目标元素定位跳转IDE中的源代码