一.引言
image.png
image.png
二.Redis介绍
image.png
image.png
三.Redis安装
3.1 安装Redis
Docker-Compose安装
version: '3.1'
services:
redis:
image: daocloud.io/library/redis:5.0.7
restart: always
container_name: redis
environment:
- TZ=Asia/Shanghai
ports:
- 6379:6379
volumes:
- ./conf/redis.conf:/usr/local/redis/redis.conf
- ./data:/data
command: ["redis-server","/usr/local/redis/redis.conf"]
3.2 使用redis-cli连接Redis
进入Redis容器的内部
docker exec -it 容器id bash
在容器内部,使用redis-cli连接
image.png
3.3 使用图形化界面连接Redis
https://github.com/lework/RedisDesktopManager-Windows/releases
image.png
四. Redis常用命令
4.1 Redis存储数据的结构
常用的5中数据结构
key-string: 一个key对应一个值
key-hash: 一个key对应一个Map
key-list: 一个key对应一个列表
key-set: 一个key对应一个集合
key-zset:一个key对应一个有序的集合
image.png
五种常用的数据结构图
image.png
key-string: 最常用的,一般用于存储一个值。
key-hash: 存储一个对象数据的。
key-list: 使用list结构实现栈和队列结构
key-set: 交集,并集,差集的操作
key-zset: 排行榜,积分存储等操作
4.2 string常用命令
#1. 添加值
set key value
# 2. 取值
get key
#3. 批量操作
mset key value [key value...]
mget key [key...]
#4. 自增命令(自增1)
incr key
#5. 自减命令(自减1)
decr key
#6. 自增或自减指定数量
incrby key increment
decrby key increment
#7. 设置值的同时,指定生存时间(每次向Redis中添加数据时,尽量都设置上生存时间)
setex key value
#8. 设置值,如果当前key不存在的话(如果这个key存在,什么事都不做,如果这个key不存在,和set命令一样)
#9. 在key对应的value后·,追加内容
append key value
#10. 查看value字符串的长度
strlen key
4.3 hash常用命令
#1. 存储数据
hset key field value
#2. 获取数据
hget key field
#3. 批量操作
hmset key field value [field value ...]
hmget key field [field ...]
#4. 自增(指定自增的值)
hincrby key field increment
#5. 设置值(如果key-field不存在,那么就正常添加,如果存在,什么事都不做)
hsetnx key field value
#6. 检查field是否存在
hexists key field
#7. 删除key对应的field,可以删除多个
hdel key field [field ...]
#8. 获取当前hash结构中的全部field和value
hgetall key
#9. 获取当前hash结构中的全部field
hkeys key
#10. 获取当前hash结构中的全部value
hvals key
#11. 获取当前hash结构中field的数量
hlen key
4.4 list常用命令
#1. 存储数据(从左侧插入数据,从右侧插入数据)
lpush key value [value ...]
rpush key value [value...]
#2. 存储数据(如果key不存在,什么事都不做,如果key存在,但是不是list结构,什么都不做)
lpushx key value
rpushx key value
#3. 修改数据(在存储数据时,指定好你的索引位置,覆盖之前索引位置的数据,index超过整个列表的长度,也会失败)
lset key index value
#4. 弹栈方式获取数据(左侧弹出数据,从右侧弹出数据)
lpop key
rpop key
#5. 获取指定索引范围的数据(start从0开始,stop输入-1,代表最后一个,-2代表倒数第二个)
lrange key start stop
#6. 获取指定索引位置的数据
lindex key index
#7. 获取整个列表的长度
llen key
#8. 删除列表中的数据(它是删除当前列表中的count个value的值,count>0从左侧向右侧删除,count<0从右侧向左侧删除,count == 0删除列表中全部的value)
lrem key count value
#9. 保留列表中的数据(保留你指定索引范围内的数据,超过整个索引范围被移除掉)
ltrim key start stop
#10. 将一个列表中最后的一个数据,插入到另外一个列表的头部位置
rpoplpush list1 list2
4.5 set常用命令
#1. 存储数据
sadd key member [member ...]
#2. 获取数据(获取全部数据)
smembers key
#3. 随机获取一个数据(获取的同时,移除数据,count默认为1,代表弹出数据的数量)
spop key [count]
#4. 交集(取多个set集合交集)
sinter set1 set2 ...
#5. 并集(获取全部集合中的数据)
sunion set1 set2 ...
#6. 差集(获取多个集合中不一样的数据)
sdiff set1 set2 ...
#7. 删除数据
srem key member [member ...]
#8. 查看当前的set集合中是否包含这个值
sismember key member
4.6 zset的常用命令
image.png
4.7key常用命令
image.png
4.8库的常用命令
image.png
五.Java连接Redis
5.1 Jedis连接Redis
5.1.1 创建Maven工程
5.1.2 导入依赖
<!-- 1.Jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.6.0</version>
</dependency>
<!-- 2.Junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- 3. Lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
5.1.3测试
@Test
public void test(){
//1. 连接Redis
Jedis jedis = new Jedis("10.131.87.243",6379);
//2. 操作Redis = 因为Redis的命令是什么,Jedis的方法就是什么
jedis.set("name","李四");
//3. 释放资源
jedis.close();
}
@Test
public void test2(){
//1. 连接Redis
Jedis jedis = new Jedis("10.131.87.243",6379);
//2. 操作Redis = 因为Redis的命令是什么,Jedis的方法就是什么
String name = jedis.get("name");
System.out.println(name);
//3. 释放资源
jedis.close();
}
image.png
image.png
5.2 Jedis存储一个对象到Redis中以byte[]形式
5.2.1导入依赖
<!-- 4. 导入spring-context-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.8</version>
</dependency>
5.2.2编写一个实体类User
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
private Integer id;
private String name;
private Date birthday;
}
5.2.3编写测试方法
@Test
public void setByteArray(){
//1. 连接Redis服务
Jedis jedis = new Jedis("10.131.87.243",6379);
//2.1 装备key-value
String key = "user";
User value = new User(1,"张三",new Date());
//2.2 将key和value转换成byte[]
byte[] byteKey = SerializationUtils.serialize(key);
byte[] byteValue = SerializationUtils.serialize(value);
//2.3 将key和value存储到Redis
jedis.set(byteKey,byteValue);
//3.释放资源
jedis.close();
}
@Test
public void getByteArray(){
//1. 连接Redis服务
Jedis jedis = new Jedis("10.131.87.243",6379);
//2.1 装备key
String key = "user";
//2.2 将key转换成byte[]
byte[] byteKey = SerializationUtils.serialize(key);
//2.3 jedis从Redis中取出value
byte[] bytes = jedis.get(byteKey);
//2.4将value反序列化成User对象
User user = (User) SerializationUtils.deserialize(bytes);
//2.5输出
System.out.println(user);
//3.释放资源
jedis.close();
}
image.png
image.png
5.3Jedis存储一个对象到Redis以String的形式
5.3.1导入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
5.3.2测试类
public class Demo3 {
@Test
public void setString(){
//1. 连接Redis
Jedis jedis = new Jedis("10.131.87.243",6379);
//2.1 准备Key,和value
String key = "user";
User value = new User(1,"张三",new Date());
//2.2 将对象转成字符串
String stringValue = JSON.toJSONString(value);
//2.3存储到Redis中
jedis.set(key,stringValue);
//3. 释放资源
jedis.close();
}
@Test
public void getString(){
//1. 连接Redis
Jedis jedis = new Jedis("10.131.87.243",6379);
//2.1 准备Key,和value
String key = "user";
//2.2 从Redis中获取value
String s = jedis.get(key);
//2.3 将value反序列化成User
User user = JSON.parseObject(s, User.class);
//2.4输出
System.out.println(user);
//3. 释放资源
jedis.close();
}
}
image.png
image.png
5.4Jedsi连接池的操作
image.png
5.5Redis的管道操作
image.png
image.png
六. Redis其他配置及集群
6.1Redis的AUTH
在配置文件中编写AUTH密码信息
# Redis的AUTH密码
# requirepass xxxx
# RDB持久化机制的配置
# save代表RDB执行的时机
# 900秒之内,有一个key改变了,就执行RDB持久化
save 900 1
save 300 10
save 60 10000
# 开启RDB持久化的压缩
rdbcompression yes
# RDB持久化文件的名称
dbfilename redis.rdb
# AOF持久化策略
# 代表开启AOF持久化
appendonly yes
# AOF持久化文件的名称
appendfilename "redis.aof"
# AOF持久化执行的时机
#appendfsync always
appendfsync everysec
#appendfsync no
image.png
image.png
image.png
6.2Redis的事务
image.png
6.3Redis持久化机制
6.3.1 RDB(Redis Database)
image.png
6.3.2 AOF(Append-only file)
image.png
image.png
6.4Redis的主从架构
image.png
docker-compose.yml
version: "3.1"
services:
redis1:
image: daocloud.io/library/redis:5.0.7
restart: always
container_name: redis1
environment:
- TZ=Asia/Shanghai
ports:
- 7001:6379
volumes:
- ./conf/redis1.conf:/usr/local/redis/redis.conf
- ./conf/sentinel1.conf:/data/sentinel.conf
command: ["redis-server","/usr/local/redis/redis.conf"]
redis2:
image: daocloud.io/library/redis:5.0.7
restart: always
container_name: redis2
environment:
- TZ=Asia/Shanghai
ports:
- 7002:6379
volumes:
- ./conf/redis2.conf:/usr/local/redis/redis.conf
- ./conf/sentinel2.conf:/data/sentinel.conf
links:
- redis1:master
command: ["redis-server","/usr/local/redis/redis.conf"]
redis3:
image: daocloud.io/library/redis:5.0.7
restart: always
container_name: redis3
environment:
- TZ=Asia/Shanghai
ports:
- 7003:6379
volumes:
- ./conf/redis3.conf:/usr/local/redis/redis.conf
- ./conf/sentinel3.conf:/data/sentinel.conf
links:
- redis1:master
command: ["redis-server","/usr/local/redis/redis.conf"]
image.png
6.5 哨兵
image.png
image.png
配置文件中的内容
image.png
在Redis容器内部启动sentinel即可
redis-sentinel sentinel.conf
6.6Redis的集群
image.png
准备yml文件
version: "3.1"
services:
redis1:
image: daocloud.io/library/redis:5.0.7
restart: always
container_name: redis1
environment:
- TZ=Asia/Shanghai
ports:
- 7001:7001
- 17001:17001
volumes:
- ./conf/redis1.conf:/usr/local/redis/redis.conf
command: ["redis-server","/usr/local/redis/redis.conf"]
redis2:
image: daocloud.io/library/redis:5.0.7
restart: always
container_name: redis2
environment:
- TZ=Asia/Shanghai
ports:
- 7002:7002
- 17002:17002
volumes:
- ./conf/redis2.conf:/usr/local/redis/redis.conf
command: ["redis-server","/usr/local/redis/redis.conf"]
redis3:
image: daocloud.io/library/redis:5.0.7
restart: always
container_name: redis3
environment:
- TZ=Asia/Shanghai
ports:
- 7003:7003
- 17003:17003
volumes:
- ./conf/redis3.conf:/usr/local/redis/redis.conf
command: ["redis-server","/usr/local/redis/redis.conf"]
redis4:
image: daocloud.io/library/redis:5.0.7
restart: always
container_name: redis4
environment:
- TZ=Asia/Shanghai
ports:
- 7004:7004
- 17004:17004
volumes:
- ./conf/redis4.conf:/usr/local/redis/redis.conf
command: ["redis-server","/usr/local/redis/redis.conf"]
redis5:
image: daocloud.io/library/redis:5.0.7
restart: always
container_name: redis5
environment:
- TZ=Asia/Shanghai
ports:
- 7005:7005
- 17005:17005
volumes:
- ./conf/redis5.conf:/usr/local/redis/redis.conf
command: ["redis-server","/usr/local/redis/redis.conf"]
redis6:
image: daocloud.io/library/redis:5.0.7
restart: always
container_name: redis6
environment:
- TZ=Asia/Shanghai
ports:
- 7006:7006
- 17006:17006
volumes:
- ./conf/redis6.conf:/usr/local/redis/redis.conf
command: ["redis-server","/usr/local/redis/redis.conf"]
image.png
image.png
image.png
image.png
6.7Java连接Redis集群
image.png
七、Redis常见问题[重点]
7.1Redis如何删除过期键
常见的删除策略有以下3种:
- 定时删除
在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作。
- 惰性删除
放任过期键不管,每次从键空间中获取键时,检查该键是否过期,如果过期,就删除该键,如果没有过期,就返回该键。
- 定期删除
每隔一段时间,程序对数据库进行一次检查,删除里面的过期键,至于要删除哪些数据库的哪些过期键,则由算法决定。
其中定时删除和定期删除为主动删除策略,惰性删除为被动删除策略。
7.2Redsi的淘汰机制
image.png
7.3缓存的常见问题
缓存穿透
image.png
缓存击穿
image.png
缓存雪崩
image.png
缓存倾斜
image.png