SpringBoot整合redis

目录

SpringBoot整合redis

1、集成jedis

2、集成lettuce

3、集成RedisTemplate

4、redis解决乱码问题

5、springboot连接redis集群


SpringBoot整合redis

1、集成jedis

1、添加依赖

         <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>5.0.2</version>
        </dependency>

 示例:

public class JdeisTest {
    public static void main(String[] args) {

        //连接redis
        Jedis jedis = new Jedis("192.168.200.129",6379);
        //密码
        jedis.auth("123456");
        System.out.println(jedis.ping());

        //keys
        Set<String> keys = jedis.keys("*");
        System.out.println(keys);

        //string
        jedis.set("jedis","hello-jedis");
        System.out.println(jedis.get("jedis"));
        jedis.expire("jedis",10L);

        //list
        jedis.lpush("list","list1","list2","list3","list4","list5");
        List<String> list = jedis.lrange("list", 0, -1);
        for (String s : list) {
            System.out.println(s);
        }
        //set
        jedis.sadd("set","set1");
        jedis.sadd("set","set2");
        jedis.sadd("set","set3");
        Set<String> set = jedis.smembers("set");
        for (String s : set) {
            System.out.println(s);
        }
        //从存储在键处的设置值中删除指定成员
        long set1 = jedis.srem("set", "1");

        //hash
        jedis.hset("hash","username","lisi");
        System.out.println(jedis.hget("hash","username"));
        Map map = new HashMap();
        map.put("age","20");
        map.put("address","杭州");
        jedis.hmset("hash2", map);
        List<String> hash = jedis.hmget("hash2","age","address");
        for (String s : hash) {
            System.out.println(s);
        }
        //zset
        jedis.zadd("zset",10d,"zset1");
        jedis.zadd("zset",10d,"zset2");
        List<String> zset = jedis.zrange("zset", 0, -1);
        for (String member : zset) {
            System.out.println(member);
        }

    }
}

 结果:

优点:

  1. 简单易用:Jedis提供了简洁的API,使得与Redis进行交互变得简单和直观。
  2. 良好的性能:Jedis是一个轻量级的框架,它使用直接的、高效的Redis协议与数据库进行通信,具有较低的延迟和较高的吞吐量。
  3. 多样的功能:Jedis支持Redis的各种功能,如字符串操作、哈希表、列表、集合、有序集合等等,可以满足大部分的应用需求。
  4. 支持连接池:Jedis提供了连接池的支持,可以管理和复用多个Redis连接,提高资源利用率和性能。
  5. 开源社区支持:Jedis是一个开源项目,拥有活跃的开源社区,用户可以从社区中获取支持、解决问题以及共享经验。

缺点:

  1. 异步操作限制:Jedis在执行命令时是同步的,即发送命令后会阻塞等待结果返回,这在某些场景下可能会影响性能。虽然Jedis提供了异步操作的支持,但是相对于其他异步框架来说,其功能有限。
  2. 单线程模型:Jedis基于Redis的单线程模型,这意味着在处理大量并发请求时,Jedis可能会受到性能瓶颈的限制。然而,对于大多数应用场景来说,Redis的单线程模型已经足够满足需求。
  3. 功能相对较少:尽管Jedis支持Redis的核心功能,但是一些高级特性(如事务、发布订阅)的支持相对有限。如果需要使用更复杂的功能,可能需要使用其他Redis客户端或者直接使用Redis的原生命令。
2、集成lettuce

添加依赖

         <dependency>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
            <version>6.2.6.RELEASE</version>
        </dependency>
public class LettuceTest {
    public static void main(String[] args) {

        //使用构建器链式编程来builder我们RedisURI
        RedisURI uri = RedisURI.builder()
                .withHost("192.168.200.129")
                .withPort(6379).
                        withAuthentication("default", "123456")
                .build();
        //创建连接交白
        RedisClient redisClient = RedisClient.create(uri);
        StatefulRedisConnection<String, String> connect = redisClient.connect();
        //通过connect 创建操作的command
        RedisCommands<String, String> command = connect.sync();

        List<String> keys = command.keys("*");
        System.out.println("keys:" + keys);

        command.set("name", "三张");
        System.out.println(command.get("name"));
        //list
        command.lpush("list","list1","list2","list3","list4","list5");
        List<String> list = command.lrange("list", 0, -1);
        for (String s : list) {
            System.out.println(s);
        }
        //set
        command.sadd("set","set1");
        command.sadd("set","set2");
        command.sadd("set","set3");
        Set<String> set = command.smembers("set");
        for (String s : set) {
            System.out.println(s);
        }

        //hash
        command.hset("hash","username","lisi");
        System.out.println(command.hget("hash","username"));
        Map map = new HashMap();
        map.put("age","20");
        map.put("address","杭州");
        command.hmset("hash2", map);
        List<KeyValue<String, String>> hmget = command.hmget("hash2", "age", "address");
        for (KeyValue<String, String> stringStringKeyValue : hmget) {
            System.out.println(stringStringKeyValue);
        }
        //zset
        command.zadd("zset",10d,"zset1");
        command.zadd("zset",10d,"zset2");
        List<String> zset = command.zrange("zset", 0, -1);
        for (String member : zset) {
            System.out.println(member);
        }
        //释放资源
        connect.close();
        redisClient.close();


    }
}

优点:

  1. 异步和响应式支持:Lettuce基于Netty框架实现,提供了异步和响应式编程模型的支持。这使得在高并发环境下能够更好地利用系统资源,并提供更好的性能和扩展性。
  2. 高性能:由于基于Netty的异步非阻塞IO模型,Lettuce能够处理大量并发连接和请求,具有较低的延迟和较高的吞吐量。
  3. 集群和高可用支持:Lettuce提供了对Redis集群和高可用性(如Redis Sentinel和Redis Cluster)的全面支持,方便在分布式环境中使用Redis。
  4. 可扩展性:Lettuce支持连接池的管理和复用,可以有效地管理多个Redis连接,并且可以配置连接池的相关参数以适应不同的业务需求。
  5. 可靠性和稳定性:Lettuce通过维护TCP连接和心跳机制来保持与Redis服务器的连接,并提供自动重连功能,以应对网络中断或Redis服务器重启等异常情况。

缺点:

  1. 学习曲线较陡峭:相对于Jedis来说,Lettuce的学习曲线较陡峭,尤其是对于那些不熟悉异步和响应式编程模型的开发者来说。需要一定的时间和精力去理解和适应这种编程模型。
  2. 功能相对较少:尽管Lettuce支持Redis的核心功能,但相对于一些高级特性(如事务、发布订阅)的支持可能较为有限。在使用Lettuce时,如果需要使用这些特性,可能需要通过其他方式实现或使用Redis的原生命令。
3、集成RedisTemplate

创建一个springboot工程

添加依赖

         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>

配置redis文件

spring:
  redis:
    port: 6379  #端口号
    host: 192.168.200.129 #虚拟机IP地址
    password: 123456 #密码
    database: 0 #redis默认数据库
    timeout: 5000

 写测试方法

public class RedisTemplateTest {
     private static StringRedisTemplate redisTemplate;

    @Autowired()
    public void setRedisTemplate(StringRedisTemplate redisTemplate) {
        RedisTools.redisTemplate = redisTemplate;
    }

    public static void stringDemo() {
        // 设置字符串值
        redisTemplate.opsForValue().set("key1", "value1");
        // 获取字符串值
        String value = redisTemplate.opsForValue().get("key1");
        System.out.println("String value: " + value);
    }

    public static void listDemo() {
        // 在列表左侧插入元素
        redisTemplate.opsForList().leftPush("list1", "value1");
        redisTemplate.opsForList().leftPush("list1", "value2");

        // 获取列表范围内的元素
        List<String> values = redisTemplate.opsForList().range("list1", 0, -1);
        System.out.println("List values: " + values);
    }

    public static void setDemo() {
        // 向集合中添加元素
        redisTemplate.opsForSet().add("set1", "value1");
        redisTemplate.opsForSet().add("set1", "value2");

        // 获取集合所有元素
        Set<String> values = redisTemplate.opsForSet().members("set1");
        System.out.println("Set values: " + values);
    }

    public static void hashDemo() {
        // 设置哈希字段的值
        redisTemplate.opsForHash().put("hash1", "field1", "value1");
        redisTemplate.opsForHash().put("hash1", "field2", "value2");

        // 获取哈希字段的值
        String value = (String) redisTemplate.opsForHash().get("hash1", "field1");
        System.out.println("Hash value: " + value);
    }

    // 添加成员到有序集合
    public static void addToZSet() {
        // 添加成员到有序集合
        redisTemplate.opsForZSet().add("myset", "Alice", 90);
        redisTemplate.opsForZSet().add("myset", "Bob", 85);
        redisTemplate.opsForZSet().add("myset", "Charlie", 95);
        redisTemplate.opsForZSet().add("myset", "David", 80);
    }

    // 获取有序集合的成员列表
    public static Set<String> getZSetMembers() {
        return redisTemplate.opsForZSet().range("myset", 0, -1);
    }

    // 获取有序集合的成员列表及分数
    public static Set<ZSetOperations.TypedTuple<String>> getZSetWithScores() {
        return redisTemplate.opsForZSet().rangeWithScores("myset", 0, -1);
    }
}

 写controller测试

@GetMapping("/")
    public String index(){
        RedisTools.get("k1");
        RedisTools.stringDemo();
        RedisTools.listDemo();
        RedisTools.setDemo();
        RedisTools.hashDemo();
        RedisTools.addToZSet();
        Set<String> zSetMembers = RedisTools.getZSetMembers();
        System.out.println(zSetMembers);
        Set<ZSetOperations.TypedTuple<String>> zSetWithScores =                     ·  
        RedisTools.getZSetWithScores();
        for (ZSetOperations.TypedTuple<String> tuple : zSetWithScores) {
            String member = tuple.getValue();
            double score = tuple.getScore();
            System.out.println("Member: " + member + ", Score: " + score);
        }
        System.out.println("------------------");
       
    }

启动项目:访问8080

4、redis解决乱码问题

当我们使用redisTemplate,保存对象时会出现乱码的现象

解决方案1、创建使用StringRedisTemplate 对象

解决方案2、我们自己定义RedisTemplate模板

@Configuration
public class RedisConfig {

   @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        // 将template 泛型设置为 <String, Object>
        RedisTemplate<String, Object> template = new RedisTemplate();
        // 连接工厂,不必修改
        template.setConnectionFactory(redisConnectionFactory);
        /*
         * 序列化设置
         */
        // key、hash的key 采用 String序列化方式
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        // value、hash的value 采用 Jackson 序列化方式
        template.setValueSerializer(RedisSerializer.json());
        template.setHashValueSerializer(RedisSerializer.json());
        template.afterPropertiesSet();
        
        return template;
    }
}

 注:如果使用java代码设置的中文值,在redis-cli中查看是中文乱码
1、如果是这种乱码:

"\"bbbb\xe5\x9f\xba\xe5\xb0\xbc\xe5\xa4\xaa\xe7\xbe\x8e\""

那么解决办法是,启动redis-cli的时候,后面加“–raw”后缀,就可以了  

5、springboot连接redis集群

1、添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
</dependency>

2、修改yml文件

spring:
  redis:
    password: 123456 #密码
    cluster:
      max-redirects: 3
      nodes: 192.168.111.185:6381,192.168.111.185:6382,192.168.111.184:6383,192.168.111.184:6384
    lettuce:
      pool:
        max-active: 8
        max-wait: -1ms
        max-idle: 8
        min-idle: 0
  • spring.redis.password: 这是连接Redis所需的密码。

  • spring.redis.cluster.max-redirects: 这是Redis Cluster在执行命令时的最大重定向次数。默认值是3

  • spring.redis.cluster.nodes: 这是Redis Cluster的节点信息。在这个例子中,有四个节点,分别是192.168.111.185:6381192.168.111.185:6382192.168.111.184:6383192.168.111.184:6384。每个节点由IP地址和端口号组成,用逗号分隔。

  • spring.redis.lettuce.pool.max-active: 这是Lettuce连接池的最大活动连接数。默认值是8

  • spring.redis.lettuce.pool.max-wait: 这是Lettuce连接池中获取连接时的最大等待时间。默认值是-1ms,表示无限等待。

  • spring.redis.lettuce.pool.max-idle: 这是Lettuce连接池的最大空闲连接数。默认值是8

  • spring.redis.lettuce.pool.min-idle: 这是Lettuce连接池的最小空闲连接数。默认值是0

 3、启动项目测试

注意:当有一个主机宕机时,springboot会报错

原因:SpringBoot客户端没有动态感知到RedisCluster的最新集群信息

解决方案:刷新节点集群拓扑动态感应

yml添加一下配置

#支持集群拓扑动态感应刷新,自适应拓扑刷新是否使用所有可用的更新,默认false关团
spring.redis.lettuce.cluster.refresh.adaptive=true
#定时刷新
spring.redis.lettuce.cluster.refresh.period=2000

  • 21
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值