Jedis、Spring-data-redis的配置以及区别

Jedis如何配置

  1. jedis引入依赖
1
2
3
4
5
<!--        Jedis引入依赖-->	
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
  1. 连接Redis客户端

    1. Jedis直连

      1
      2
      3
      Jedis jedis = new Jedis("192.168.30.0", 6379);	
      jedis.set("hello", "world");
      String value = jedis.get("hello");
    2. JedisPool 连接池的使用

      配置文件jedis.properties

      1
      2
      3
      4
      5
      6
      7
      8
      # 资源池最大连接数
      maxTotal=50
      # 资源池允许最大空闲连接数
      maxIdle=10
      # redis服务器地址
      host=192.168.30.0
      # redis开放端口
      port=6379

      JedisUtils.java

      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
      29
      30
      31
      32
      33
      34
      35
      import redis.clients.jedis.Jedis;
      import redis.clients.jedis.JedisPool;
      import redis.clients.jedis.JedisPoolConfig;

      import java.io.IOException;
      import java.io.InputStream;
      import java.util.Properties;

      public class JedisUtils {
      //创建一个连接池
      private static JedisPool jedisPool;
      //
      static{
      //读取配置文件
      InputStream is = JedisUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
      Properties pro=new Properties();
      try {
      pro.load(is);
      } catch (IOException e) {
      e.printStackTrace();
      }
      //连接池配置
      JedisPoolConfig config=new JedisPoolConfig();
      config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
      config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));

      //初始化连接池,把对应参数传递进去
      jedisPool=new JedisPool(config,pro.getProperty("host"), Integer.parseInt(pro.getProperty("port")));
      }

      //设置好后返回,返回一个Jedis对象
      public static Jedis getJedis(){
      return jedisPool.getResource();
      }
      }

      测试类JedisTest.java

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      public static void main(String[] args) {
      Jedis jedis = null;
      try {
      //获取连接池对象
      jedis = JedisUtils.getJedis();
      //执行操作
      jedis.set("java", "good");
      System.out.println(jedis.get("java"));
      } catch (Exception e) {
      e.printStackTrace();
      } finally {
      if (jedis != null) {
      //这里使用的close不代表关闭连接,指的是归还资源
      jedis.close();
      }

      }
      }
  2. Jedis直连与Jedis连接池使用的对比

    方案 优点 缺点
    Jedis直连 简单方便
    适用于连接数较少且使用时间较长,可构成长连接场景
    存在每次新建/关闭TCP开销
    资源无法控制,存在连接泄露的可能
    Jedis对象线程不安全
    Jedis连接池 Jedis预先生成,降低开销
    连接池的形成保护和控制资源的使用
    相对于直连,使用相对麻烦,尤其在资源管理上需要很多参数来保证,一旦规划不合理就会出现问题

Spring-data-redis如何配置

  1. spring-data-redis引入依赖
1
2
3
4
5
6
7
8
9
10
11
<!--        redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.0</version>
</dependency>
  1. 添加配置文件application.properties
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#Redis服务器地址
spring.redis.host=192.168.30.0
#Redis服务器连接端口(默认端口为6379
spring.redis.port=6379
#Redis数据库索引(默认位0
spring.redis.database=0
#连接超时时间(毫秒)
spring.redis.timeout=1800000
#连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=20
#最大阻塞等待时间(复数表示没有限制)
spring.redis.lettuce.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=5
#连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=0
  1. 添加Redis配置类RedisConfig.java
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@EnableCaching
@Configuration
public class RedisConfig {

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate();
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setConnectionFactory(factory);
template.setKeySerializer(redisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
return template;
}

@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}

  1. 创建Controller试验一下
1
2
3
4
5
6
7
8
9
10
11
12
13
@RestController
@RequestMapping("/redisTest")
public class RedisTestControllor {
@Autowired
private RedisTemplate redisTemplate;

@GetMapping
public String testRedis(){
redisTemplate.opsForValue().set("name","zeker");
String name = (String) redisTemplate.opsForValue().get("name");
return name;
}
}
  1. 根据自己开设的端口访问http://localhost:8080/redisTest

1

常见问题及解决方法

Could not get a resource from the pool; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 192.168.30.0:6379

1、查看是否启动Redis服务器

2、查看目标IP地址是否可以ping通

3、Redis的配置application.yml(或application.properties)中spring.redis.timeout连接超时时间(毫秒)中设置不能为0

4、修改redis的配置文件redis.conf

  1. protected-mode yes 改为 protected-mode no
    (该配置项表示是否开启保护模式,默认是开启,开启后Redis只会本地进行访问,拒绝外部访问)
  2. 注释掉 bin127.0.0.1 即 #bin 127.0.0.1
    (PS: 不注释掉,表示指定 Redis 只接收来自于该 IP 地址的请求,注释掉后,则表示将处理所有请求)

修改配置文件redis.conf后记得保存重启redis

5、如果在Redis中没有配置requirepass,那么在application.properties(或application.yaml)中就不要写spring.redis.password

6、开放对应端口

1
2
firewall-cmd --permanent --add-port=6379/tcp	# 开放6379端口号
firewall-cmd --query-port=6379/tcp # 查看端口号是否打开

PS:云服务器需在安全组中设置对应端口号,不建议开放所有端口。在虚拟机上测试也可以选择关闭防火墙systemctl stop firewalld

总结

Jedis是Redis官方推荐的面向Java的操作Redis的客户端,而RedisTemplateSpring-data-redis中对JedisApi的高度封装。

Spring-data-redis相对于Jedis来说可以方便地更换Redis的Java客户端,比Jedis多了自动管理连接池的特性,方便与其他Spring框架进行搭配使用

总体来说,Jedis,更像spring 与 MySQL结合,通过操作连接池,获取实例操作数据库,而Spring-data-redis与spring的整合,更像spring 与 mybatis整合,通过工厂,创建实例,再操作实例。