张小驰出没 张小驰出没
首页
  • Spring合集
  • SpringMVC合集
  • Mybatis合集
  • Spring Boot合集
  • Mybatis-plus合集
  • Spring Security合集
  • Vue合集
  • Redis合集
  • RabbitMQ合集
  • 数据结构

    • 数据结构
  • 算法解析

    • 日常算法
    • 剑指Offer
    • LeetCode
  • 技术与Bug

    • 技术文档
    • Bug解决方法
  • 个人博客

    • Hexo博客搭建
  • 我的项目
  • 我的面试
  • 分类
  • 标签
  • 归档
友链
关于
Hexo
GitHub

MoYu

何德何能,何其荣幸
首页
  • Spring合集
  • SpringMVC合集
  • Mybatis合集
  • Spring Boot合集
  • Mybatis-plus合集
  • Spring Security合集
  • Vue合集
  • Redis合集
  • RabbitMQ合集
  • 数据结构

    • 数据结构
  • 算法解析

    • 日常算法
    • 剑指Offer
    • LeetCode
  • 技术与Bug

    • 技术文档
    • Bug解决方法
  • 个人博客

    • Hexo博客搭建
  • 我的项目
  • 我的面试
  • 分类
  • 标签
  • 归档
友链
关于
Hexo
GitHub
  • Spring合集

  • SpringMVC合集

  • Mybatis合集

  • Spring Boot合集

  • Mybatis-plus合集

  • Spring Security合集

  • Redis合集

    • 初识Redis
    • Redis入门命令
    • Redis数据类型及命令
    • Redis事务操作
    • Jedis与Redis
    • SpringBoot整合Redis
      • 整合Redis
        • 1.创建项目
        • 2.配置redis信息
        • 3.Redis操作
        • 4.测试类运行
      • 序列化问题
        • 1.查看原有配置类
        • 2.Dome测试
        • 3.创建配置类
      • Redis.conf详解
    • Redis持久化
    • Redis发布订阅
    • Redis主从复制
    • Redis缓存穿透和雪崩
  • Vue合集

  • RabbitMQ合集

  • 学习ing
  • Redis合集
MoYu
2021-06-21

SpringBoot整合Redis

# SpringBoot整合Redis

# 整合Redis

在SpringBoot2.x之后,原来使用的jedis被替换为了lettuce

**jedis:**采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用jedis pool连接池 , 更像BIO模式

**lettuce:**采用netty,实例可以再多个线程中进行共享,不存在线程不安全的情况!可以减少线程数据了,更像NO模式

# 1.创建项目

首先创建一个SpringBoot项目,注入依赖如下:

1

# 2.配置redis信息

spring.redis.host=127.0.0.1
spring.redis.port=6379
# 一共16个数据库,0-15 可以自行选择 或者不配置
# spring.redis.database=1
1
2
3
4

# 3.Redis操作

首先注入 RedisTemplate

@Autowired
private RedisTemplate redisTemplate;
1
2

# 3.1 基本操作

对于常用的基本操作,可以使用 redisTemplate 直接调用方法,例如:

//移除一个元素
redisTemplate.move();
//开启事务
redisTemplate.multi();
//结束事务
redisTemplate.discard();
//执行事务
redisTemplate.exec();
//等等等.....
1
2
3
4
5
6
7
8
9

# 3.2 redis数据类型命令

// 操作String字符串
ValueOperations String = redisTemplate.opsForValue();
// 操作List列表
ListOperations list = redisTemplate.opsForList();
// 操作Hash哈希
HashOperations hash = redisTemplate.opsForHash();
// 操作Set集合
SetOperations set = redisTemplate.opsForSet();
// 操作Zset有序集合
ZSetOperations zSet = redisTemplate.opsForZSet();
// 操作Geospatial地理位置
GeoOperations geospatial  = redisTemplate.opsForGeo();
// 操作HyperLogLog基数统计
HyperLogLogOperations hyperLogLog = redisTemplate.opsForHyperLogLog();
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 3.3 清空数据库

RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
//清空本数据库
connection.flushDb();
//清空全部数据库
connection.flushAll();
1
2
3
4
5

# 4.测试类运行

@Autowired
private RedisTemplate redisTemplate;

@Test
void contextLoads() {
    RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
    connection.flushDb();
    redisTemplate.opsForValue().set("k", "v");
    redisTemplate.opsForValue().set("z", "c");
    System.out.println(redisTemplate.opsForValue().get("k"));
    Set keys = redisTemplate.keys("*");
    for (Object key : keys) {
        System.out.print(key+"、");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

2

出现问题:

Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1:6379

这是因为:你的 redis-server 没有开启 , 开启之后再试试

# 序列化问题

上面我们已经初步SpringBoot整合好了Redis,也可以正常运行出结果,看似没什么问题

但是,这个时候我们使用Redis自带的redis-cli查看下:

3

会发现出现了乱码,这就是序列化问题,也说明我们需要自己编写一个redisTemplate配置类

# 1.查看原有配置类

查看RedisAutoConfiguration类:

@Bean
@ConditionalOnMissingBean(
    name = {"redisTemplate"}
)
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
    RedisTemplate<Object, Object> template = new RedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}
1
2
3
4
5
6
7
8
9
10

可以看出它的返回类型为 RedisTemplate<Object, Object> , 而我们需要的是<String, Object>,所以我们进行改写

# 2.Dome测试

# 2.1 创建实体类

该类用于测试对象的传递与获取

@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String name;
    private int age;
}
1
2
3
4
5
6
7
8

# 2.2 存取测试

@Test
void test()  {
    RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
    connection.flushDb();

    User user = new User("zc", 18);
    redisTemplate.opsForValue().set("user",jsonUser);
    System.out.println(redisTemplate.opsForValue().get("user"));
}
1
2
3
4
5
6
7
8
9

4

很明显这是,这是没有序列化问题,我们用方法将其序列化

@Test
void test() throws JsonProcessingException {
    RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
    connection.flushDb();

    User user = new User("zc", 18);
    //转化为json对象,进行序列化
    String jsonUser = new ObjectMapper().writeValueAsString(user);
    redisTemplate.opsForValue().set("user",jsonUser);
    System.out.println(redisTemplate.opsForValue().get("user"));
}
1
2
3
4
5
6
7
8
9
10
11

5

也可以单纯修改实体类

@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
    private String name;
    private int age;
}
1
2
3
4
5
6
7
8

6

这时候,使用 redis-cli 进行查看

6

# 3.创建配置类

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        //我们为了自己开发方便,一般直接使用<String,object
        RedisTemplate<String,Object> template = new RedisTemplate<String,Object>();
        template.setConnectionFactory(factory);
        //序列化配置
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        //String的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        //key采用string的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        //hash的key也采用string的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        //value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //hash的value序列化方式采用iackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();

        return template;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

这时候运行测试,是正常的,然后我们打开redis-cli查看

8

# Redis.conf详解

这个文件我们可以使用Linux查看最新版的:

正常安装的redis,应该在/usr/local/bin中

cd /usr/local/bin       #进入该路径下

cd config               #这里我是安装时就将redis.conf移动到了该文件夹下,进入

vim redis.conf          #查看该文件,也可以进行修改
1
2
3
4
5

单位 :单位对大小写不敏感

9

**包含:**可以包含多个配置文件

10

网络

bind 127.0.0.1      #绑定ip

protected-mode yes  #保护模式

port 6379           #端口号
1
2
3
4
5

通用 GENERAL

daemonize yes            #以守护进程的方式运行,默认是no,我们需要自己开启为yes

pidfile /var/run/redis_6379.pid  #如果以后台的方式运行,我们就需要指定一个pid文件

#日志
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel notice
logfile ""       #日志的文件位置名

databases 16     #数据库的数量,默认是16个数据库

always-show-logo yes  #是否显示logo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

快照

持久化,在规定的时间内,执行了多少次操作,则会持久化到文件.rdb.aof

redis是内存数据库,如果没有持久化,那么数据断电立刻失去

#如果900s内,如果至少有一个1 key进行了修改,我们及进行持久化操作
save 900 1
#如果300s内,如果至少10 key进行了修改,我们及进行持久化操作
save 300 10
#如果605内,如果至少10000 key行了修改,我们及进行持久化操作
save 60 10000

stop-writes-on-bgsave-error yes     #持久化出错,是否继续工作

rdbcompression yes      #是否压缩 rdb 文件 , 需要消耗一些cpu资源

rdbchecksum yes         #保存rdb文件的时候,进行错误的检查校验

dir ./                   #rdb文件保存的目录
1
2
3
4
5
6
7
8
9
10
11
12
13
14

SECURITY 安全

127.0.0.1:6379> ping                         #正常默认没有密码
PONG
127.0.0.1:6379> config get requirepass       #查看现在的密码
1) "requirepass"
2) ""
127.0.0.1:6379> config set requirepass 123456 #设置密码为123456
OK
127.0.0.1:6379> ping                         #新开一个窗口,无法连接
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth 123456                  #登录账号密码
OK
127.0.0.1:6379> ping                         #可以连接
PONG
127.0.0.1:6379> config set requirepass ''    #取消密码
OK
127.0.0.1:6379> config get requirepass       #查看当面当前
1) "requirepass"
2) ""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

CLIENTS 限制

maxclients 10000              #设置能连接上redis的最大客户端的数量
maxmemory <bytes>             #redis配置最大的内存容量
maxmemory-policy noeviction   #内存到达上限之后的处理策略

1.volatile-1ru:只对设置了过期时间的key进行LRU(默认值)
2.allkeys-Tru:删除1ru算法的key
3.volatile-random:随机删除即将过期key
4.al1keys-random:随机删除
5.volatile-ttl:删除即将过期的
6.noeviction:永不过期,返回错误
1
2
3
4
5
6
7
8
9
10

APPEND ONLY模式 aof配置

appendonly no        #默认是不开启aof模式的,默认是使用rdb方式持久化的,在大部分所有的情况下,rdb完全够用!

appendfilename" appendonly.aof"   #持久化的文件的名字

#appendfsync always      #每次修改都会sync。消耗性能
appendfsync everysec     #每秒执行一次sync,可能会损失这1s的数据
#appendfsync no          #不执行sync,这个时候操作系统自己同步数据,速度最快
1
2
3
4
5
6
7
#Redis
Jedis与Redis
Redis持久化

← Jedis与Redis Redis持久化→

最近更新
01
链表
01-25
02
约瑟夫问题
01-25
03
快慢指针
01-25
更多文章>
Theme by Vdoing | Copyright © 2021-2022 MoYu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式