Redis 常见功能详解及 Spring Cloud 集成代码展示

Redis 常见功能详解及 Spring Cloud 集成代码展示


一、Redis 核心功能详解

1. 数据结构与功能
数据类型特点适用场景
String二进制安全缓存、计数器、分布式锁
Hash键值对集合对象存储、属性更新
List有序可重复消息队列、最新列表
Set无序唯一标签系统、共同好友
Sorted Set有序唯一排行榜、优先级队列
Bitmap位操作用户签到、活跃统计
HyperLogLog基数估算UV 统计
Stream消息流事件溯源、消息队列
2. 高级特性
  • 事务MULTI/EXEC 命令组
  • Lua 脚本:原子执行复杂操作
  • 发布订阅:实时消息通知
  • 持久化
    • RDB:定时快照
    • AOF:记录所有写操作
  • 集群模式
    • 主从复制:读写分离
    • 哨兵模式:自动故障转移
    • Cluster:分片存储(16384 slots)
3. 典型应用场景
# 分布式锁
SET lock_key unique_value NX PX 30000

# 滑动窗口限流
ZADD requests 1640995200000 req1
ZREMRANGEBYSCORE requests -inf (1640995200000-60000)
ZCARD requests

# 排行榜
ZADD leaderboard 95 "user1"
ZREVRANGE leaderboard 0 2 WITHSCORES

# 布隆过滤器
BF.ADD users user123
BF.EXISTS users user123

二、Spring Cloud 集成 Redis

1. 依赖配置
<!-- pom.xml -->
<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>
# application.yml
spring:
  redis:
    host: redis-server
    port: 6379
    password: yourpassword
    database: 0
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: 1000ms
2. 基础操作模板
@Autowired
private RedisTemplate<String, Object> redisTemplate;

// String 操作
redisTemplate.opsForValue().set("user:1001", "Alice", 30, TimeUnit.MINUTES);
String user = (String) redisTemplate.opsForValue().get("user:1001");

// Hash 操作
redisTemplate.opsForHash().put("user_profile:1001", "email", "alice@example.com");
Object email = redisTemplate.opsForHash().get("user_profile:1001", "email");

// List 操作
redisTemplate.opsForList().rightPush("notifications", "New message");
List<Object> messages = redisTemplate.opsForList().range("notifications", 0, -1);

// Set 操作
redisTemplate.opsForSet().add("user:1001:followers", "user2001", "user2002");
Set<Object> followers = redisTemplate.opsForSet().members("user:1001:followers");
3. 分布式锁实现
public boolean tryLock(String lockKey, String requestId, long expireTime) {
    return redisTemplate.execute((RedisCallback<Boolean>) connection -> {
        RedisStringCommands commands = connection.stringCommands();
        byte[] key = lockKey.getBytes();
        byte[] value = requestId.getBytes();
        Boolean result = commands.set(key, value, 
            Expiration.seconds(expireTime), 
            RedisStringCommands.SetOption.SET_IF_ABSENT
        );
        return result != null && result;
    });
}

public boolean releaseLock(String lockKey, String requestId) {
    String script = "if redis.call('get', KEYS[1]) == ARGV[1] " +
                   "then return redis.call('del', KEYS[1]) " +
                   "else return 0 end";
    DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);
    Long result = redisTemplate.execute(redisScript, Collections.singletonList(lockKey), requestId);
    return result != null && result == 1;
}
4. 缓存注解使用
@Configuration
@EnableCaching
public class RedisCacheConfig {
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
        return RedisCacheManager.builder(factory)
            .cacheDefaults(RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(30))
                .disableCachingNullValues())
            .build();
    }
}

@Service
public class ProductService {
    @Cacheable(value = "products", key = "#id")
    public Product getProductById(Long id) {
        // 数据库查询逻辑
    }

    @CachePut(value = "products", key = "#product.id")
    public Product updateProduct(Product product) {
        // 更新数据库
        return product;
    }

    @CacheEvict(value = "products", key = "#id")
    public void deleteProduct(Long id) {
        // 删除数据库记录
    }
}
5. 发布订阅模式
// 发布者
@Autowired
private RedisTemplate<String, Object> redisTemplate;

public void sendMessage(String channel, String message) {
    redisTemplate.convertAndSend(channel, message);
}

// 订阅者
@Component
public class MessageSubscriber implements MessageListener {
    @Override
    public void onMessage(Message message, byte[] pattern) {
        String channel = new String(message.getChannel());
        String body = new String(message.getBody());
        System.out.println("Received: " + body + " from " + channel);
    }
}

// 配置订阅
@Configuration
public class RedisConfig {
    @Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory factory,
                                                  MessageListenerAdapter listenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(factory);
        container.addMessageListener(listenerAdapter, new PatternTopic("news.*"));
        return container;
    }

    @Bean
    public MessageListenerAdapter listenerAdapter(MessageSubscriber subscriber) {
        return new MessageListenerAdapter(subscriber, "onMessage");
    }
}
6. Redisson 高级集成
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.17.7</version>
</dependency>
# application.yml
spring:
  redis:
    redisson:
      config: |
        singleServerConfig:
          address: "redis://redis-server:6379"
          password: "yourpassword"
          database: 0
// 分布式锁使用
@Autowired
private RedissonClient redissonClient;

public void processWithLock() {
    RLock lock = redissonClient.getLock("resourceLock");
    try {
        if (lock.tryLock(10, 60, TimeUnit.SECONDS)) {
            // 受保护的资源操作
        }
    } finally {
        lock.unlock();
    }
}

// 分布式集合
RSet<Object> globalSet = redissonClient.getSet("globalDataSet");
RMap<String, Object> distributedMap = redissonClient.getMap("sharedConfig");

三、最佳实践与性能优化

  1. 键值设计规范

    • 使用命名空间:业务:模块:key(如 order:payments:1001
    • 控制 Key 长度(< 1KB)
    • 避免 BigKey(String < 10KB,集合元素 < 5000)
  2. 连接池配置

    lettuce:
      pool:
        max-active: 16   # 最大连接数
        max-idle: 8      # 最大空闲连接
        min-idle: 2      # 最小空闲连接
        max-wait: 2000ms # 获取连接最大等待时间
    
  3. 管道与批量操作

    List<Object> results = redisTemplate.executePipelined((RedisCallback<Object>) connection -> {
        for (int i = 0; i < 1000; i++) {
            connection.stringCommands().set(("key:" + i).getBytes(), 
                                           ("value:" + i).getBytes());
        }
        return null;
    });
    
  4. 内存优化策略

    • 启用内存淘汰策略:maxmemory-policy volatile-lru
    • 使用 Hash 分片存储大对象
    • 对长文本启用压缩

四、常见问题解决方案

  1. 缓存穿透

    // 布隆过滤器解决方案
    @Component
    public class BloomFilterService {
        private static final String BLOOM_FILTER = "user_filter";
        
        @Autowired
        private RedisTemplate<String, Object> redisTemplate;
        
        public void addUser(String userId) {
            redisTemplate.opsForValue().setBit(BLOOM_FILTER, 
                    hash(userId) % 2^32, true);
        }
        
        public boolean mightExist(String userId) {
            return Boolean.TRUE.equals(redisTemplate.opsForValue()
                    .getBit(BLOOM_FILTER, hash(userId) % 2^32));
        }
        
        private long hash(String value) {
            return Hashing.murmur3_128().hashString(value, StandardCharsets.UTF_8).asLong();
        }
    }
    
  2. 缓存雪崩

    • 策略:随机过期时间 + 热点数据永不过期
    @Cacheable(value="products", key="#id", 
               unless="#result == null",
               cacheResolver = "randomTtlCacheResolver")
    
  3. 缓存一致性

    • 双写模式:先更新 DB 再删除缓存
    • 异步刷新:通过 Canal 监听 binlog 更新缓存
  4. 集群模式下事务

    // 使用 Hash Tag 确保 key 在相同 slot
    redisTemplate.opsForValue().set("{user}:1001:profile", data);
    redisTemplate.opsForValue().set("{user}:1001:orders", orders);
    

五、监控与运维

  1. 关键监控指标

    • 内存使用率:used_memory
    • 命中率:keyspace_hits / (keyspace_hits + keyspace_misses)
    • 连接数:connected_clients
    • 持久化状态:rdb_last_bgsave_status
  2. 常用运维命令

    # 内存分析
    redis-cli --bigkeys
    redis-cli --memkeys
    
    # 慢查询分析
    CONFIG SET slowlog-log-slower-than 10000
    SLOWLOG GET 10
    
  3. Spring Boot Actuator 集成

    management:
      endpoints:
        web:
          exposure:
            include: health,metrics,redis
      metrics:
        tags:
          application: ${spring.application.name}
    

生产建议

  1. 使用 Redis 6.0+ 支持 TLS 加密传输
  2. 启用 ACL 访问控制
  3. 定期备份 RDB 文件到云存储
  4. 使用 Redis Exporter + Prometheus + Grafana 监控体系

以上内容涵盖 Redis 核心功能和 Spring Cloud 集成方案,可根据实际需求调整实现细节。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值