Day 27:分布式缓存与 Redis

目标:掌握分布式缓存的基本概念,学习如何使用 Redis 缓存数据。

理论知识

1. 分布式缓存的作用与应用场景
  • 作用

    • 提高访问速度:缓存热点数据,减少数据库查询次数。
    • 减轻数据库压力:缓解高并发场景下数据库的性能瓶颈。
    • 实现分布式架构:通过缓存共享数据,支持分布式系统。
  • 应用场景

    • 热点数据查询(如商品详情、用户信息)。
    • 会话管理(如分布式 Session)。
    • 计数器(如点赞数、访问量)。
2. Redis 的基本概念
  • Redis 是什么

    • 高性能的内存数据库,支持多种数据结构。
    • 支持持久化,将数据存储到磁盘,避免数据丢失。
  • 常用数据类型

    • String:简单的键值对。
    • List:链表,支持队列和栈操作。
    • Set:集合,支持去重和交并差集操作。
    • Hash:哈希表,适合存储对象数据。
    • Sorted Set:有序集合,支持排序。
3. 缓存常见问题与解决方案
  • 缓存穿透

    • 问题:查询的 key 不存在,直接穿透到数据库。
    • 解决方案:对空值进行缓存,或者使用布隆过滤器。
  • 缓存雪崩

    • 问题:大量缓存同时过期,导致请求涌入数据库。
    • 解决方案:为缓存设置随机过期时间,避免同时失效。
  • 缓存击穿

    • 问题:热点 key 过期,瞬时高并发请求击穿缓存。
    • 解决方案:使用互斥锁(分布式锁)保护缓存重建。
4. Redis 与数据库结合使用
  • 典型场景

    • 查询数据时,先查缓存,再查数据库。
    • 数据更新时,及时更新缓存,或使用延迟双删策略。
  • 流程

    1. 查询缓存,如果命中则直接返回。
    2. 如果未命中,查询数据库并将结果写入缓存。
    3. 设置缓存过期时间,保持数据一致性。

实践操作

1. 配置 Redis 客户端
  1. 安装 Redis

    • 使用 Docker 安装 Redis:
      docker run -d --name redis -p 6379:6379 redis
      
    • 添加依赖: 在 pom.xml 中添加 Redis 的客户端依赖(推荐使用 Lettuce):
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-redis</artifactId>
      </dependency>
      
    • 配置 Redis: 在 application.yml 中配置 Redis 的连接信息:
      spring:
        redis:
          host: localhost
          port: 6379
          lettuce:
            pool:
              max-active: 8
              max-idle: 8
              min-idle: 0
          timeout: 2000ms
      
  2. 使用 Redis 缓存数据
    2.1 创建 Redis 工具类

    使用 RedisTemplate 操作 Redis:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Component;
    
    import java.util.concurrent.TimeUnit;
    
    @Component
    public class RedisUtil {
    
        @Autowired
        private RedisTemplate<String, Object> redisTemplate;
    
        // 写入缓存
        public void set(String key, Object value, long timeout) {
            redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
        }
    
        // 读取缓存
        public Object get(String key) {
            return redisTemplate.opsForValue().get(key);
        }
    
        // 删除缓存
        public void delete(String key) {
            redisTemplate.delete(key);
        }
    }
    
    2.2 缓存用户信息

    创建一个简单的用户管理服务,利用 Redis 缓存用户数据:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.HashMap;
    import java.util.Map;
    
    @Service
    public class UserService {
    
        @Autowired
        private RedisUtil redisUtil;
    
        private static final String USER_CACHE_KEY_PREFIX = "user:";
    
        // 模拟数据库
        private static final Map<Long, String> DATABASE = new HashMap<>();
    
        static {
            DATABASE.put(1L, "Alice");
            DATABASE.put(2L, "Bob");
            DATABASE.put(3L, "Charlie");
        }
    
        // 获取用户信息
        public String getUserById(Long userId) {
            String cacheKey = USER_CACHE_KEY_PREFIX + userId;
    
            // 查询缓存
            Object cachedUser = redisUtil.get(cacheKey);
            if (cachedUser != null) {
                return (String) cachedUser;
            }
    
            // 查询数据库
            String user = DATABASE.get(userId);
            if (user != null) {
                redisUtil.set(cacheKey, user, 300); // 缓存 5 分钟
            }
            return user;
        }
    }
    
    2.3 测试接口

    创建一个 Controller,提供用户查询接口:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        @GetMapping("/user")
        public String getUser(@RequestParam Long userId) {
            return userService.getUserById(userId);
        }
    }
    

总结

  1. 理论掌握

    • 分布式缓存的作用与 Redis 的基本概念。
    • 缓存穿透、缓存雪崩、缓存击穿的解决方案。
  2. 实践收获

    • 使用 Spring Boot 集成 Redis,实现数据的缓存。
    • 通过 RedisTemplate 实现缓存的增删查操作。
  3. 进一步扩展

    • 学习 Redis 的高级特性,如事务、Lua 脚本和分布式锁。
    • 在实际项目中结合 Redis 哨兵模式或集群部署,提升可用性和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值