Redisson 与 Spring Data Redis:区别详解

内容分享2周前发布
0 1 0

在日常的Java企业级开发中,Redis作为高性能的分布式缓存和数据存储解决方案,已经成为不可或缺的一环。在Spring生态中,我们最常接触的是
spring-boot-starter-data-redis,但与此同时,
Redisson 这个名字也频繁出现。

许多开发者会产生疑问:它们俩是什么关系?我该如何选择?能否同时使用?本文将从概念、配置到使用场景,为你彻底解析这两者的区别与联合使用的最佳实践。

一、核心定位:本质区别是什么?

第一,必须明确一个核心观点:Redisson 和 Spring Data Redis 并非相互替代的关系,而是为解决不同层面问题而设计的工具,它们可以完美协同工作。

为了更好地理解,我们来看一个详细的对比表格:

特性维度

Spring Data Redis

Redisson

核心定位

数据访问层框架

分布式服务框架

主要目标

简化对Redis数据的CRUD操作,提供统一的缓存抽象。

基于Redis实现分布式Java对象和服务,简化分布式应用开发。

编程接口

RedisTemplate, StringRedisTemplate

RedissonClient

功能侧重

基础数据结构操作:String, Hash, List, Set, ZSet等。核心场景是缓存

高级分布式功能:分布式锁、限流器、分布式集合、原子类、远程服务等。

编程模型

模板方法模式,直接操作数据。

侵入式更强,提供实现了java.util接口的分布式对象(如RMap对标Map)。

关系类比

类似于 JdbcTemplate之于数据库,是数据访问的工具。

类似于一个基于Redis的分布式工具包,提供现成的分布式解决方案。

简单来说:

  • Spring Data Redis 让你能方便地操作存储在Redis里的数据
  • Redisson 让你能方便地实现分布式系统里的各种功能,而Redis只是它实现这些功能的底层存储和通信媒介。

二、为什么及如何共存?

由于定位不同,在实际项目中,我们完全有理由同时使用它们:

  • 使用 Spring Data Redis 的 @Cacheable注解或 RedisTemplate来做简单的数据缓存。
  • 使用 Redisson 的分布式锁来保证集群环境下关键业务的原子性。

关键结论:它们是两个独立的Redis客户端,可以配置为连接同一个Redis服务器,互不干扰。

最佳共存配置实践

为了避免Spring Boot自动装配可能带来的配置歧义(例如,Redisson错误地使用了默认的localhost连接),我们推荐显式地、手动地配置各自的连接

1. 配置 Spring Data Redis (以Lettuce为例)

application.yml

spring:
  redis:
    host: your-redis-host
    port: 6379
    password: your-password # 可选
    database: 0 # 可选

Java配置类 (RedisConfig.java)

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);

        // 使用String序列化器来序列化Key
        StringRedisSerializer stringSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringSerializer);
        template.setHashKeySerializer(stringSerializer);

        // 使用JSON序列化器来序列化Value,提高可读性
        GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer();
        template.setValueSerializer(jsonSerializer);
        template.setHashValueSerializer(jsonSerializer);

        return template;
    }
}

2. 配置 Redisson

Java配置类 (RedissonConfig.java)

@Configuration
public class RedissonConfig {

    @Value("${spring.redis.host}")
    private String redisHost;

    @Value("${spring.redis.port}")
    private String redisPort;

    @Bean(destroyMethod = "shutdown") // 确保应用关闭时Redisson客户端也优雅关闭
    public RedissonClient redissonClient() {
        Config config = new Config();
        // 单节点模式配置
        config.useSingleServer()
                .setAddress(String.format("redis://%s:%s", redisHost, redisPort));
                // .setPassword("your-password") // 如果设置了密码

        return Redisson.create(config);
    }
}

注意:这里Redisson的配置复用了application.yml中spring.redis的配置,避免了配置信息重复。你也可以使用spring.redisson.config属性进行完全独立的配置。

三、使用场景指南

目前,我们可以在代码中根据不同的业务场景,灵活地注入并使用这两个客户端了。

@Service
public class BusinessService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate; // 用于缓存

    @Autowired
    private RedissonClient redissonClient; // 用于分布式锁

    public void doBusiness(String productId) {
        // 场景1:使用Spring Data Redis进行缓存查询
        String cacheKey = "product:" + productId;
        Object cachedProduct = redisTemplate.opsForValue().get(cacheKey);
        if (cachedProduct != null) {
            return; // 命中缓存,直接返回
        }

        // 场景2:使用Redisson获取分布式锁,防止缓存击穿
        RLock lock = redissonClient.getLock("lock:" + productId);
        try {
            // 尝试加锁,最多等待10秒,上锁后30秒自动解锁
            boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);
            if (isLocked) {
                // 再次检查缓存(双重检查锁定)
                cachedProduct = redisTemplate.opsForValue().get(cacheKey);
                if (cachedProduct != null) {
                    return;
                }
                // ... 从数据库查询数据 ...
                Object productFromDB = getFromDB(productId);
                // ... 将数据写入缓存 ...
                redisTemplate.opsForValue().set(cacheKey, productFromDB, 1, TimeUnit.HOURS);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            // 释放锁
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
}

四、总结与选择

项目需求

推荐方案

理由

仅需简单缓存

Spring Data Redis

配置简单,与Spring生态无缝集成,轻量高效。

仅需分布式锁、限流等高级功能

Redisson

开箱即用,功能强劲,API直观,避免了重复造轮子。

混合场景(最常见)

两者共存

强强联合,利用各自优势。用RedisTemplate做缓存,用RedissonClient处理分布式同步问题。

最终提议

对于大多数分布式Spring Boot项目,采用两者共存的方案是最佳实践。遵循本文的显式配置方式,可以清晰地将它们的职责分离开来,让你的应用既拥有简洁的数据缓存能力,也具备强劲的分布式服务功能,从而构建出更加健壮和可扩展的系统。

希望这篇指南能协助你清晰地理解Redisson和Spring Data Redis,并在你的项目中做出最合适的技术选型与架构设计。

© 版权声明

相关文章

1 条评论

您必须登录才能参与评论!
立即登录
  • 头像
    Super小宇_2019 投稿者

    收藏了,感谢分享

    无记录