Jedis

Jedis Client 是 Redis 官方推荐的一个面向 Java 客户端,库文件实现了对各类 API 进行封装调用

<!-- pom.xml -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.3.1</version>
</dependency>
@Slf4j
public class JedisDemo {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("192.168.111.185", 6379);
        jedis.auth("111111");
 
        log.info("redis conn status:{}", "连接成功");
        log.info("redis ping retvalue:{}", jedis.ping());
 
        jedis.set("k1", "jedis");
        log.info("k1 value:{}", jedis.get("k1"));
    }
}

Lettuce

Jedis 和 Lettuce 都是 Redis 的客户端,都可以连接 Redis 服务器,在 SpringBoot 2.0 之后默认使用 Lettuce

  • Jedis 连接 Redis 服务器:每个线程都要创建 Jedis 实例,有很多线程时,不仅开销大需要反复的创建关闭一个 Jedis 连接,而且也是线程不安全的
  • Lettuce 底层使用 Netty,当有多个线程都需要连接 Redis 服务器时,可以保证只创建—个 Lettuce 连接,使所有的线程共享这一个 Lettuce 连接
<!-- pom.xml -->
<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>6.2.1.RELEASE</version>
</dependency>
@Slf4j
public class LettuceDemo {
    public static void main(String[] args) {
        // 使用构建器 RedisURI.builder
        RedisURI uri = RedisURI.builder()
                .redis("192.168.111.181")
                .withPort(6379)
                .withAuthentication("default","111111")
                .build();
        // 创建连接客户端
        RedisClient client = RedisClient.create(uri);
        StatefulRedisConnection conn = client.connect();
        // 操作命令 API
        RedisCommands<String, String> commands = conn.sync();
 
		commands.set("k1", "1111");
	    String s1 = commands.get("k1");
	    System.out.println("String s ===" + s1);
 
        // 关闭
        conn.close();
        client.shutdown();
    }
}

RedisTemplate(推荐)

SpringBoot 与 Redis 整合

<!-- pom.xml -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>
# application.ymal
 
# ======================== Redis 单机 =====================
spring.redis.database=0
spring.redis.host=192.168.111.185
spring.redis.port=6379
spring.redis.password=111111
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
 
# ======================== Redis 集群 =====================
spring.redis.password=111111
spring.redis.cluster.max-redirects=3 # 获取失败 最大重定向次数
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
spring.redis.cluster.nodes=192.168.111.175:6381,192.168.111.175:6382,192.168.111.172:6383
 
# SpringBoot 2.x 后,Redis 默认的连接池采用 Lettuce,当 Redis 集群节点发生变化后,Letture 默认是不会刷新节点拓扑,需要配置:
# 支持集群拓扑动态感应刷新,自适应拓扑刷新是否使用所有可用的更新,默认 false 关闭
spring.redis.lettuce.cluster.refresh.adaptive=true
# 定时刷新
spring.redis.lettuce.cluster.refresh.period=2000

配置类:

package com.xxx.redis-study.config;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
 
@Configuration
public class RedisConfig {
    /**
     * Redis 序列化的工具配置类,配置序列化
     * > keys *
     * 1) "ord:102"                        // 序列化过
     * 2) "\xac\xed\x00\x05t\x00\aord:102" // 没有序列化过
     * 
     * this.redisTemplate.opsForValue(); // 操作 string 的所有方法
     * this.redisTemplate.opsForList();  // 操作 list 的所有方法
     * this.redisTemplate.opsForSet();   // 操作 set 的所有方法
     * this.redisTemplate.opsForHash();  // 操作 hash 的所有方法
     * this.redisTemplate.opsForZSet();  // 操作 zset 的所有方法
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
 
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        // 设置 key 序列化方式 string
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //设置 value 的序列化方式 json,使用 GenericJackson2JsonRedisSerializer 替换默认序列化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
 
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
 
        redisTemplate.afterPropertiesSet();
 
        return redisTemplate;
    }
}

使用:

package com.xxx.redis-study.service;
 
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
 
import javax.annotation.Resource;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
 
@Service
@Slf4j
public class OrderService {
    public static final String ORDER_KEY = "order:";
 
    @Resource
    private RedisTemplate redisTemplate;
 
    public void addOrder() {
        int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;
        String orderNo = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(ORDER_KEY + keyId, orderNo);
        log.info("编号 [" + keyId + "] 的订单流水生成: {}", orderNo);
    }
 
    public String getOrderById(Integer id) {
        return (String) redisTemplate.opsForValue().get(ORDER_KEY + id);
    }
}