Redis的使用总结

时间:2025-04-23 08:01:45

Redis 核心使用场景

  1. 缓存加速

    • 高频访问数据缓存(如商品信息、用户信息)

    • 缓解数据库压力,提升响应速度

  2. 会话存储

    • 分布式系统共享 Session(替代 Tomcat Session)

    • 支持 TTL 自动过期

  3. 排行榜/计数器

    • 实时排序(Sorted Set 实现)

    • 文章阅读量/点赞数统计(INCR 命令)

  4. 消息队列

    • List 实现简单队列(LPUSH/BRPOP)

    • Streams 实现可靠消息队列(Redis 5.0+)

  5. 分布式锁

    • SETNX 命令实现互斥锁

    • Redisson 客户端封装分布式锁

  6. 实时系统

    • 用户行为记录(最近搜索、浏览历史)

    • 实时数据统计(在线人数、地理位置)

Redis 数据类型与典型应用

数据类型 结构特征 典型场景 操作命令示例
String 二进制安全文本/数值 缓存、计数器、分布式锁 SET/GET/INCR/DECR
Hash 字段值映射表 存储对象(用户信息、商品详情) HSET/HGET/HGETALL
List 双向链表 消息队列、最新消息列表 LPUSH/RPOP/LRANGE
Set 无序唯一集合 标签系统、共同好友 SADD/SMEMBERS/SINTER
ZSet 有序分值集合 排行榜、延迟队列 ZADD/ZRANGE/ZREVRANGE
Stream 消息流(持久化队列) 消息队列(支持消费者组) XADD/XREAD/XGROUP
BitMap 位操作 签到统计、用户画像 SETBIT/BITCOUNT/BITOP
HyperLogLog 基数估算算法 UV 统计(去重计数) PFADD/PFCOUNT

键(Key)命名规范

  1. 层级结构业务模块:子模块:唯一标识

    • 示例:user:profile:1001

  2. 命名原则

    • 长度 ≤ 100 字符

    • 避免特殊字符(推荐字母数字 + 冒号)

    • 可读性优先(如 order:status:2024

Spring Boot 集成实践

1. 添加依赖
<!-- Spring Data Redis -->
<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>
2. 配置参数 (application.yml)
spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password: yourpassword
    lettuce:
      pool:
        max-active: 20
        max-idle: 10
        min-idle: 5
3. 核心组件配置
@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(RedisSerializer.string());
        template.setValueSerializer(RedisSerializer.json());
        return template;
    }
    
    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
        return new StringRedisTemplate(factory);
    }
}
4. 使用示例
@Component
public class UserService {
    private final RedisTemplate<String, User> redisTemplate;

    // 存储用户信息
    public void cacheUser(User user) {
        redisTemplate.opsForValue().set("user:" + user.getId(), user, 30, TimeUnit.MINUTES);
    }

    // 获取用户信息
    public User getCachedUser(Long userId) {
        return redisTemplate.opsForValue().get("user:" + userId);
    }

    // 使用 Hash 存储对象
    public void cacheUserProfile(Long userId, Map<String, String> profile) {
        redisTemplate.opsForHash().putAll("user:profile:" + userId, profile);
    }
}
5. 注解缓存支持
@Configuration
@EnableCaching
public class CacheConfig {
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        return RedisCacheManager.builder(factory)
                .cacheDefaults(RedisCacheConfiguration.defaultCacheConfig()
                        .entryTtl(Duration.ofHours(1)))
                .build();
    }
}

// 业务使用
@Service
public class ProductService {
    @Cacheable(value = "products", key = "#productId")
    public Product getProductById(String productId) {
        // 数据库查询逻辑
    }
}

最佳实践建议

  1. 连接池配置:合理设置 max-active 防止连接耗尽

  2. 序列化选择:优先使用 JSON 序列化(Jackson2JsonRedisSerializer)

  3. 大Key规避:String 类型 value ≤ 10KB,集合元素 ≤ 1万

  4. 事务限制:Redis 事务非原子性,推荐使用 Lua 脚本

  5. 监控告警:集成 Prometheus + Grafana 监控 QPS、内存等指标

缓存穿透缓存雪崩缓存击穿

问题 定义 后果 解决方案
缓存穿透 请求的数据在缓存和数据库中都不存在 大量无效请求打到数据库 缓存空值、布隆过滤器、请求数据基础格式校验
缓存雪崩 大量缓存同时过期,导致请求打到数据库 数据库压力骤增,可能崩溃 随机过期时间、多级缓存、限流与降级、热点数据永不过期
缓存击穿 热点 key 过期时,大量请求同时访问 数据库压力瞬间增大 互斥锁、逻辑过期、提前刷新