Redis

关注公众号 jb51net

关闭
首页 > 数据库 > Redis > Redis框架项目应用

Redis框架在项目中的实战

作者:Vivienne_ChenW

Lettuce是一款高性能、异步非阻塞的 Redis 客户端,基于Netty框架开发,也是Spring Boot 2.x 及以上版本默认的 Redis 客户端客户端(Lettuce)只需配置哨兵节点地址和主节点名称,本文介绍Redis框架在项目中的实战,感兴趣的朋友一起看看吧

一、Redis 哨兵模式(Redis Sentinel)

Redis Sentinel 是 Redis 官方提供的高可用解决方案,核心作用是监控 Redis 主从集群、自动完成主从切换、通知客户端主节点变更,解决单机 Redis 宕机后无法自动恢复的问题。

Lettuce 是一款高性能、异步非阻塞的 Redis 客户端,基于 Netty 框架开发,也是 Spring Boot 2.x 及以上版本默认的 Redis 客户端客户端(Lettuce)只需配置哨兵节点地址和主节点名称,无需知道主从节点的具体地址,哨兵会自动告知客户端当前的主节点。

二、Lettuce 和Redission 如何选择

在实际项目中,Lettuce 和 Redisson 是互补使用的 ——Lettuce 作为底层高性能 Redis 客户端负责基础通信,Redisson 基于 Lettuce 封装了丰富的分布式数据结构和服务(如分布式锁、分布式 Map),既发挥 Lettuce 的性能优势,又利用 Redisson 简化业务开发。

  1. 依赖引入(pom.xml)
<!-- Spring Boot 整合 Redis(默认内置 Lettuce) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- Redisson 核心依赖(适配 Spring Boot) -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.23.0</version> <!-- 选稳定版本 -->
</dependency>
redis.lettuce.client.enable=true # 启用Lettuce客户端
# 连接池配置(核心)
redis.lettuce.client.pool.minIdle=6 # 最小空闲连接(保活)
redis.lettuce.client.pool.maxIdle=21 # 最大空闲连接
redis.lettuce.client.pool.maxTotal=100 # 最大连接数
redis.lettuce.client.pool.maxWaitMillis=4000 # 最大等待时间
redis.lettuce.client.sentinel.mastername=master # 监控的主节点名称
redis.lettuce.client.sentinel.password=***
redis.lettuce.client.sentinel.database=0
redis.lettuce.client.sentinel.nodeInfo[0]=10.193.114.0:26379 # 哨兵节点列表
redis.lettuce.client.sentinel.nodeInfo[0]=10.193.114.2:26379 # 哨兵节点列表
redis.lettuce.client.sentinel.nodeInfo[0]=10.193.114.3:26379 # 哨兵节点列表

三、代码示例

场景 1:用 Lettuce 做基础缓存读写(Spring RedisTemplate)
Spring Data Redis 封装了 Lettuce,提供 RedisTemplate 简化操作,这是项目中最基础的用法:

@Component
public class CacheService {
    // 注入 Spring 封装的 RedisTemplate(底层是 Lettuce)
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    // 存储合约基础信息(String 类型)
    public void setTestInfo(String testKey, Object testInfo) {
        // 底层通过 Lettuce 发送 SET 命令到 Redis 哨兵集群
        redisTemplate.opsForValue().set(
            testKey, 
            testInfo, 
            1, // 过期时间 1 小时
            TimeUnit.HOURS
        );
    }

    public Object getTestInfo(String testKey) {
        // 底层通过 Lettuce 发送 GET 命令
        return redisTemplate.opsForValue().get(testKey);
    }

    // 异步操作(Lettuce 核心优势,高并发场景用)
    public void setTestInfoAsync(String testKey, Object testInfo) {
        // 异步设置,不阻塞主线程(高并发场景推荐)
        redisTemplate.opsForValue().setAsync(testKey, testInfo);
    }
}

场景 2:用 Redisson 操作分布式 Map(对应你的 INFO:TEST_KEY)
Redisson 封装的 RMap 是分布式 Map,比 Lettuce 的 Hash 更易用,支持自动序列化 / 反序列化:

@Component
public class TestMapService {
    // 注入 RedissonClient(底层复用 Lettuce 连接)
    @Resource
    private RedissonClient redissonClient;

    // 批量存储合约信息到分布式 Map
    public void batchSaveTestInfo(List<TestInfoPO> testList) {
        // 获取 Redis 中的分布式 Map(INFO:TEST_KEY)
        RMap<String, TestInfoPO> testMap = 
            redissonClient.getMap("INFO:TEST_KEY");
        
        // 批量存入:INFO:TEST_KEY
        testList.forEach(d -> {
            String key = ...
            testMap.put(key, d); // 原子操作,线程安全
        });
    }

    // 获取单个test信息
    public TestInfoPO getTestInfo(String testId) {
        RMap<String, TestInfoPO> testMap = redissonClient.getMap("INFO:TEST_KEY");
        String key = ...;
        return testMap.get(key);
    }
}

场景 3:用 Redisson 实现分布式锁(防并发修改)

@Component
public class UpdateService {
    @Resource
    private RedissonClient redissonClient;

    // 修改(加分布式锁)
    public void updateTestInfo(String testtId, TestInfoPO newInfo) {
        // 1. 定义锁的唯一标识
        String lockKey = "lock:test:update:" + testId;
        RLock lock = redissonClient.getLock(lockKey);

        try {
            // 2. 获取锁:最多等5秒,持有锁10秒(自动释放,防止死锁)
            boolean locked = lock.tryLock(5, 10, TimeUnit.SECONDS);
            if (!locked) {
                throw new RuntimeException("正在修改中,请稍后重试");
            }

            // 3. 执行业务逻辑
            // ... 你的更新数据库/缓存逻辑 ...

        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("获取锁失败", e);
        } finally {
            // 4. 释放锁(必须在 finally 中,防止锁泄露)
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
}

四、项目中的最佳实践

  1. 分工明确:简单的缓存读写(String/Hash)用 RedisTemplate(底层 Lettuce);
  2. 分布式锁、分布式集合、延迟队列等复杂场景用 Redisson;
  3. 复用连接池:让 Redisson 复用 Lettuce 的连接池配置,避免重复创建连接;
  4. 异步优先:高并发场景(如期货行情缓存)用 Lettuce 的异步 API(setAsync/getAsync),提升吞吐量;
  5. 锁的规范:分布式锁必须设置超时时间,且在 finally 中释放,防止死锁;
  6. 序列化配置:统一配置 RedisTemplate 的序列化方式(如 Jackson2JsonRedisSerializer),避免乱码:
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        // 设置 JSON 序列化器
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        template.setValueSerializer(serializer);
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }
}

到此这篇关于Redis框架在项目中的实战的文章就介绍到这了,更多相关Redis框架项目应用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文