一 Redis基础
1.初识Redis
1.Redis是基于内存的key-value结构数据库
优点:基于内存存储,读写性能高
适合存储热点数据(短时间被被大量用户读取的数据)
2.NoSQL,泛指非关系型数据库,是关系型数据库的补充
3.Redis应用场景:缓存,任务队列,消息队列,分布式锁
4.Liunx版Redis下载地址:https://download.redis.io/releases,下载的redis是源文件,需要进行编译安装,Windows版本百度即可
5.Linux下安装Redis
https://blog.csdn.net/shaopengjie2/article/details/126461079?spm=1001.2014.3001.5502
安装过程中如果报错:You need tcl x.x or newer in order to run the Redis test
则先安装tcl ,然后在继续后面的步骤
yum install -y tcl-devel
6.Redis中文文档地址:Redis文档中心
2.运行Redis
1.设置redis后台运行,需要在redis的配置文件redis.conf中将 daemonize 的值修改为 yes。
daemonize yes
2.修改完成之后,运行Redis时需要指定配置文件
redis-server redis.conf
(注意文件路径,redis.conf在redis根目录下)
3.进入 Redis 执行相关操作
redis-cli
4.设置redis连接密码
在redis.conf配置文件中,打开 requirepass 选项,在后面设置密码即可。
设置完成之后重启Redis服务生效。
requirepass [newpassword]
此时操作Redis则会提示 :(error) NOAUTH Authentication required.说明Redis密码已经启用。
然后提供密码即可正常操作Redis
aush [password]
或者在登录Redis时直接提供密码。
# (-h 地址,-p 端口号,-a 密码)
redis-cli -h localhost -p 6379 -a 123456
5.允许Redis远程连接:注释掉 redis.conf 文件中的 bind 127.0.0.1,即可允许 Redis 远程连接。
# bind 127.0.0.1
# bind 选项用于绑定客户端连接的IP
开启允许远程连接后需要开放Redis服务端口,重启 Redis 服务。
firewall-cmd --zone=public --add-port=6379/tcp --permanent
firewall-cmd --reload
6.Redis启动成功后默认提供了16个数据库。默认操作的是Redis的 0 号数据库,使用 select [index] 进行切换
在 redis.conf 中可对默认数据库的数量进行修改
databases 16 #修改默认数据库数量
select [index] #修改正在使用的数据库
3.Redis数据类型
1.字符串string-存储普通字符串
- set key value 设置指定key的值,key相同时后边会覆盖前边的值
- get key 获取指定key的值
- setex key seconds value 设置指定key的值并且将key的过期时间设置为 seconds 秒,典型场景:验证码
- setnex key 只有在key不存在时才设置key的值,典型场景:分布式锁
- del key 删除指定key
2.哈希hash-适合存储对象
hash是一个string类型的field和value的映射表,hash非常适合存储对象。
- hset key field value 将哈希表key中的字段field设置为value
- hget key field 获取指定key的field字段的值
- hdel key field 删除指定key的field字段的值
- hkeys key 获取哈希表中所有的字段
- hvals key 获取哈希表中所有的值
- hgetall key 获取哈希表中指定的key的所有字段和值
3.列表list -按顺序插入可重复
Redis列表是简单的字符串列表,按照插入顺序进行排序
- lpush key val1 val2 val3… 将一个或多个值插入到列表头部
- lrange key start stop 获取指定范围内的元素(stop为-1时查询所有)
- rpop key 获取并移除列表中的最后一个元素
- llen key 获取列表长度
- brpop key1 [key2] timeout 获取并移除元素的最后一个元素,如果列表中无元素则会阻塞表等到超时或发现可弹出元素为止
4.集合set-无序不重复
Redis set是string类型的无序集合,集合成员是唯一的,数据不重复
- sadd key member1 member2 向集合添加一个或多个成员
- smembers key 返回指定集合key中的全部成员
- scard key 获得指定key的成员数
- sinter key1 key2 返回给定集合的交集
- sunion key1 key2 返回给定集合的并集
- sdiff key key2 返回给定集合的差集
- srem key member 移除集合中一个或多个成员
5.有序集合 sorted set-有序不重复
sorted set有序集合是string类型的集合,且不允许元素重复,每个元素都会关联一个double类型的分数,redis使用分数来为集合排序。
- zadd key member1 member2 向有序集合添加一个或多个成员,已存在则更新该集合
- zrange key start stop 通过索引区间返回指定区间内的元素值
- zincrby key increment member 有序集合中为指定成员的分数加上增量incremnet
- zrem key member1 移除有序集合中一个或多个成员
6.通用命令
4.SpringBoot中使用Redis
在pom.xml中引入redis的坐标
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
在配置文件中配置基本信息
spring:
redis:
host: 192.168.169.133
port: 6379
password: 123456
database: 0
jedis:
pool:
max-active: 8 # 最大连接数
max-wait: 1ms # 最大阻塞时间
max-idle: 4
min-idle: 0
二 SpringBoot中使用Redis
1.引入Redis的Maven坐标,配置好环境。(参考前面的配置信息)
2.在项目中引入配置类,设置序列化器(非必须步骤,只是为了便于在reids工具中查看)。
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<Object,Object> redisTemplate=new RedisTemplate<>();
// 默认的序列化器: new JdkSerializationRedisSerializer()
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
}
3.使用自动注入 RedisTemplate 对象,使用 RedisTemplate 对象操作Reids
Redis简单示例:缓存String类型的数据
@Autowired
private RedisTemplate redisTemplate;
@GetMapping
public String getInfo(){
//Redis简单示例:缓存String类型的数据
ValueOperations valueOperations = redisTemplate.opsForValue();
valueOperations.set(key,value);
valueOperations.set(key,value,time);
valueOperations.set(key,value,TimeUnit);
//获取String类型的缓存数据
valueOperations.get(key)
//删除Redis中指定的key,通用操作直接使用redisTemplate操作即可,
redisTemplate.delete(key)
}
4.缓存其他类型的数据,使用 RedisTemplate 创建指定的对象即可。
//缓存Hash类型的数据
redisTemplate.opsForHash()
//缓存集合类型的数据
redisTemplate.opsForList()
此处内容较为简单,不再赘述。
三 Spring Boot中使用Spring Cache
Spring Cache是一个框架,实现了基于注解的缓存功能。只需要增加一个注释,就可以实现缓存功能。
Spring Cache提供了一层抽象,底层可以切换不同的Cache实现。具体就是通过CacheManager接口来统一不同的缓存技术。
CacheManager是Spring提供的各种缓存技术的抽象接口。
针对不同的缓存技术,需要实现不同的CacheManager
在Spring Boot项目中,使用缓存技术只需要在项目中导入相关缓存技术的的依赖包,并在启动类上使用 @EnableCaching 开启缓存功能即可。
例如,使用Redis作为缓存技术,只需要导入spring-data-redis的maven坐标即可。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
修改配置文件,增加cache,指定Redis作为缓存产品
spring:
cache:
redis:
time-to-live: 180000 #设置缓存过期时间
redis:
database: 0
host: 127.0.0.1
jedis:
pool:
max-idle: 8
max-wait: 1ms
max-active: 8
min-idle: 0
Spring cache常用注解说明:
使用 @CachePut 缓存数据
@Autowired
private CacheManager cacheManager;
/*
@CachePut 用于缓存返回值
value表示缓存的名称,相当于一类缓存
key表示该名称下的缓存数据的key
*/
@PostMapping
//用参数的指定属性作为key
@CachePut(value="cacheName",key="#user.id")
public UserInfo insert(UserInfo user){
//insert业务
return user;
}
@PutMapping
//用参数作为key
@CachePut(value="cacheName",key="#id")
public String update(String id){
return "shawn";
}
使用 @CacheEvict 删除缓存数据
@Autowired
private CacheManager cacheManager;
/*
@CacheEvict 用于删除缓存数据
value表示缓存的名称,相当于一类缓存
key表示该名称下的缓存数据的key
以下三种获取id值的写法是完全等价的,
*/
@DeleteMapping
@CacheEvict(value="cacheName",key="#id")
//@CacheEvict(value="cacheName",key="#p0") #p0 表示第一个参数
//@CacheEvict(value="cacheName",key="#root.args[0]") #root.args[0] 表示第一个参数
public String del(String id){
return "delete";
}
使用 @Cacheable 缓存数据
@Autowired
private CacheManager cacheManager;
/*
@CacheEvict 执行前先查看缓存中是否有数据,有数据则直接从缓存中拿数据,没有则执行方法,并将方法的结果存储到缓存中
value表示缓存的名称,相当于一类缓存
key表示该名称下的缓存数据的key
conditon表示满足条件缓存
unless 表示满足条件不缓存
*/
@GetMapping
//@Cacheable(value="cacheName",key="#id",conditon="#id!=null")
@Cacheable(value="cacheName",key="#id",unless="#return==null")
public UserInfo get(String id){
UserInfo user=service.getById(id);
return user;
}
最后,返回的类型必须实现序列化接口,否则无法进行缓存。