Java 使用 Redis

Java 使用 Redis 全攻略(2025 版)

目标:从 零到生产级,掌握 Java 生态中最成熟、最稳定的 Redis 客户端 —— Lettuce(Spring Boot 默认)与 Jedis,覆盖 单机、集群、哨兵、连接池、Pipeline、事务、Lua、监控、运维 等全场景。


1. 客户端选型对比(2025 推荐)

客户端架构性能功能维护状态推荐场景
LettuceNetty 异步5 星5 星(Cluster、Sentinel、TLS、Reactive)活跃(6.4+)生产首选
Jedis阻塞同步4 星4 星稳定(4.4+)简单项目、遗留系统
Redisson分布式对象3 星5 星(锁、队列、布隆)活跃分布式锁

结论生产用 Lettuce,复杂分布式用 Redisson


2. 环境准备

<!-- pom.xml -->
<dependencies>
    <!-- Lettuce(推荐) -->
    <dependency>
        <groupId>io.lettuce</groupId>
        <artifactId>lettuce-core</artifactId>
        <version>6.4.0.RELEASE</version>
    </dependency>

    <!-- Jedis(可选) -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>5.1.0</version>
    </dependency>

    <!-- Spring Boot(自动集成 Lettuce) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
</dependencies>

3. 基础连接(Lettuce)

3.1 单机连接

RedisClient client = RedisClient.create("redis://password@127.0.0.1:6379/0");
StatefulRedisConnection<String, String> connection = client.connect();
RedisCommands<String, String> sync = connection.sync();

sync.set("name", "JavaRedis");
System.out.println(sync.get("name")); // JavaRedis

connection.close();
client.shutdown();

3.2 连接池(Apache Commons Pool2)

GenericObjectPoolConfig<StatefulRedisConnection<String, String>> poolConfig = 
    new GenericObjectPoolConfig<>();
poolConfig.setMaxTotal(50);
poolConfig.setMaxIdle(20);
poolConfig.setMinIdle(5);
poolConfig.setTestOnBorrow(true);

RedisClient client = RedisClient.create(uri);
ConnectionPool<StatefulRedisConnection<String, String>> pool = 
    ConnectionPool.create(client, poolConfig);

try (StatefulRedisConnection<String, String> conn = pool.borrowObject()) {
    conn.sync().set("key", "value");
}

4. Spring Boot 集成(Lettuce 默认)

4.1 application.yml

spring:
  redis:
    host: redis-prod.example.com
    port: 6379
    password: YourStrongP@ssw0rd
    database: 0
    timeout: 500ms
    ssl: true
    lettuce:
      pool:
        enabled: true
        max-active: 50
        max-idle: 20
        min-idle: 5
        max-wait: 1s

4.2 使用 StringRedisTemplate

@Autowired
private StringRedisTemplate redisTemplate;

@PostConstruct
public void test() {
    redisTemplate.opsForValue().set("boot:key", "Spring Boot + Lettuce");
    System.out.println(redisTemplate.opsForValue().get("boot:key"));
}

4.3 自定义序列化(JSON)

@Configuration
public class RedisConfig {

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

        // Key: String
        template.setKeySerializer(RedisSerializer.string());
        // Value: JSON (Jackson)
        template.setValueSerializer(jackson2JsonRedisSerializer());

        template.afterPropertiesSet();
        return template;
    }

    private RedisSerializer<Object> jackson2JsonRedisSerializer() {
        Jackson2JsonRedisSerializer<Object> serializer = 
            new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(om);
        return serializer;
    }
}

5. 高可用连接

5.1 Sentinel(哨兵)

spring:
  redis:
    sentinel:
      master: mymaster
      nodes: sentinel1:26379,sentinel2:26379,sentinel3:26379
      password: sentinelPass
@Autowired
private StringRedisTemplate template; // 自动故障转移

5.2 Redis Cluster

spring:
  redis:
    cluster:
      nodes: 
        - node1:6379
        - node2:6379
        - node3:6379
      max-redirects: 3
template.opsForValue().set("{user:1000}:name", "张三"); // Hash Tag 保证同槽

6. 高级特性

6.1 Pipeline 批量操作

redisTemplate.executePipelined((RedisCallback<Object>) connection -> {
    for (int i = 0; i < 1000; i++) {
        connection.set(("key:" + i).getBytes(), ("value:" + i).getBytes());
    }
    return null;
});

6.2 事务(MULTI/EXEC)

redisTemplate.execute((RedisCallback<Object>) connection -> {
    connection.multi();
    connection.set("a".getBytes(), "1".getBytes());
    connection.incr("a".getBytes());
    return connection.exec(); // [OK, 2]
});

6.3 Lua 脚本

DefaultRedisScript<Long> script = new DefaultRedisScript<>(
    "return redis.call('INCR', KEYS[1])", Long.class);

Long result = redisTemplate.execute(script, Collections.singletonList("counter"));

7. 分布式锁(Redisson 推荐)

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.31.0</version>
</dependency>
@Autowired
private RedissonClient redisson;

public void lockedMethod() {
    RLock lock = redisson.getLock("my:lock");
    try {
        if (lock.tryLock(5, 60, TimeUnit.SECONDS)) {
            // 业务逻辑
        }
    } finally {
        lock.unlock();
    }
}

8. 性能优化

优化点配置
Pipeline批量写 > 100 条
连接池maxTotal = CPU × 50
超时timeout: 500ms
TLSssl: true
IO 线程Redis 配置 io-threads 4

9. 监控与运维

9.1 Micrometer 集成

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
management:
  metrics:
    export:
      prometheus:
        enabled: true

指标

redis_commands_duration_seconds
redis_connected_clients
redis_pool_active_connections

9.2 连接泄漏检测

@EventListener
public void handle(ContextClosedEvent event) {
    if (connection.isOpen()) {
        log.warn("Redis 连接泄漏!");
    }
}

10. 生产级配置模板

# application-prod.yml
spring:
  redis:
    host: ${REDIS_HOST}
    port: 6379
    password: ${REDIS_PASSWORD}
    database: 0
    timeout: 500ms
    ssl: true
    lettuce:
      pool:
        enabled: true
        max-active: 100
        max-idle: 30
        min-idle: 10
        max-wait: 2s
      shutdown-timeout: 100ms

management:
  metrics:
    export:
      prometheus:
        enabled: true
  endpoint:
    metrics:
      enabled: true
    prometheus:
      enabled: true

11. 常见问题与解决方案

问题原因解决方案
Redis connection lost网络抖动启用重试
MOVED 重定向连接非 Cluster 客户端使用 RedisClusterClient
Connection timed out防火墙检查安全组
MAXMEMORY OOM内存超限设置 maxmemory-policy allkeys-lru
Authentication failedACL 权限ACL SETUSER app on >pass ~* +@all

12. 一键测试工具类

@Component
public class RedisHealthChecker {

    @Autowired
    private StringRedisTemplate template;

    @Scheduled(fixedRate = 30000)
    public void check() {
        try {
            String pong = template.getConnectionFactory()
                .getConnection().ping();
            log.info("Redis 健康: {}", pong);
        } catch (Exception e) {
            log.error("Redis 连接失败", e);
        }
    }
}

13. 最佳实践清单(Checklist)

项目检查
使用 LettuceSpring Boot 默认
开启 连接池max-active 合理
启用 TLSssl: true
使用 Hash TagCluster 多 key 操作
批量操作 Pipeline> 100 条
分布式锁用 Redisson避免自研
监控 连接数、延迟Prometheus
超时 < 500ms防止阻塞
序列化用 JSON避免 JDK 序列化

小结:Java + Redis 技术栈图谱

graph TD
    A[Java 应用] --> B(Spring Boot)
    B --> C[Lettuce 客户端]
    C --> D[单机 / Sentinel / Cluster]
    B --> E[Redisson]
    E --> F[分布式锁 / 队列 / 布隆]
    C --> G[Pipeline / Lua / 事务]
    B --> H[Micrometer + Prometheus]

彩蛋:Redis 8+ Java 新特性支持

// Redis 8+ JSON 支持(Lettuce 6.4+)
sync.jsonSet("doc:1", "$", "{\"name\":\"张三\"}");
String name = sync.jsonGet("doc:1", "$.name");

需要 K8s 部署 + SidecarRedis 缓存穿透/雪崩方案分布式限流Redis Stream 消息队列Terraform 自动化配置?随时告诉我!

文章已创建 2481

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部