redisTemplate.expire 无效和更新含有生存时间的key

spring中redis 配置的不对

如下配置:

 
  1. <!--redis配置-->

  2. <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">

  3. <property name="maxIdle" value="${redis.maxIdle}" />

  4. <property name="maxTotal" value="${redis.maxActive}" />

  5. <property name="maxWaitMillis" value="${redis.maxWait}" />

  6. <property name="testOnBorrow" value="${redis.testOnBorrow}" />

  7. </bean>

  8. <!--spring redis配置-->

  9. <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"

  10. p:host-name="${redis.host}"

  11. p:port="${redis.port}"

  12. p:password="${redis.pass}"

  13. p:pool-config-ref="poolConfig"/>

  14. <!--下面是配置的关键-->

  15. <bean id="stringRedisSerializer"

  16. class="org.springframework.data.redis.serializer.StringRedisSerializer" />

  17. <!--下面可以单独使用,可以设置生存时间-->

  18. <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"

  19. p:connectionFactory-ref="connectionFactory" p:keySerializer-ref="stringRedisSerializer"

  20. p:hashKeySerializer-ref="stringRedisSerializer"

  21. p:hashValueSerializer-ref="stringRedisSerializer" />

  22.  
  23. <!--下面可以单独使用,可以设置生存时间-->

  24. <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"

  25. p:connectionFactory-ref="connectionFactory" />

使用:可以封装到dao中,也可以通过spring上下文去获取RedisTemplate或者 stringRedisTemplate来使用。举例:

 
  1. redisTemplate.expire("redisobject", 30, TimeUnit.SECONDS);

  2.  
  3.  
  4. stringRedisTemplate.expire("redis", 30, TimeUnit.SECONDS);

  5.  
  6.  
  7. //注意保证使用的key是存在的

  8. //redisTemplate.expire(key,timeout,timeunit);

  9. //参数说明 key 需要设置的key timeout:key的生存时间 timeuint:时间单位(小时,分钟,秒……)

  10. //可以用 ttl key 命令查看该key的生存时间

 

 

 

 

注意:以上的方法只适用于key对应的值不再更新的问题,如果遇到包含生命周期的值需要更新的情景就不适用了,因为set 方法会丢失该key的生存时间,变成永久有效的。

比如以下场景:一天内限制某个用户只能访问2000次服务api。

怎么做呢?把值放进hash散列里,更新hash散列不会有问题。(实际上INCR,LPUSH,HSET,ZREM指令都不会影响key的生存时间,当然list,set都是可行的,根据自己的场景选择合适的数据结构)

下面简单列一下代码,使用spring-data(不推荐使用,封装的太繁琐,不如直接使用jedis,然后写个工具类做下简单封装)

 
  1. @Override//给指定的key设定生存时间

  2. public boolean setKeyLifeTime(String key,long lifetime,TimeUnit unit){

  3. boolean result=redisTemplate.expire(key, lifetime, unit);

  4. return result;

  5. }

  6.  
  7. @Override//放入redis,更新也使用这个方法,前提key要存在

  8. public void setHash(String hashName, Object key, Object value) {

  9. redisTemplate.opsForHash().put(hashName, key, value);

  10. }

  11.  
  12. @Override//取值

  13. public Object getHash(String hashName, Object key) {

  14. return redisTemplate.opsForHash().get(hashName, key);

  15. }

 

转载于:https://my.oschina.net/mifans/blog/792446

相关资源:RedisTemplate-redis-优雅玩法_redistemplate清空redis,redis...

<think>嗯,用户之前问了Redis在拍卖系统中的作用,现在又问了后端如何使用Redis。我需要确保回答既全面又符合他们的实际需求。首先,用户可能对Redis有一定的了解,但作为后端开发人员,他们更想知道具体如何应用,比如数据结构的选择、常见操作以及最佳实践。 用户的问题里可能有拼写错误,“redia”应该是“Redis”,但根据上下文,可以推断正确。接下来要考虑用户的身份,可能是后端开发者,特别是处理高并发或实时系统的开发者,比如拍卖系统。他们可能想了解如何集成Redis到现有架构中,解决实际问题如缓存、会话管理、分布式锁等。 需要覆盖基本使用步骤,比如连接Redis、数据结构操作,然后深入实际应用场景。要避免太基础的内容,但也不能假设他们知道所有细节。比如,连接Redis的代码示例可能会有帮助,但也要说明配置注意事项,如连接池超时设置。 另外,用户之前的回答里提到了拍卖系统的具体用例,这次可能需要更通用的后端使用方式,但可以结合之前的例子,保持一致性。例如,分布式锁在拍卖中的使用,或者缓存策略如何优化性能。 还要注意用户提到的系统级指令,比如正确使用LaTeX格式,确保代码块数据结构示例正确无误。可能需要检查之前的回答结构,保持类似的格式,如分点解析代码示例。 另外,用户可能关心数据一致性问题,如何保证Redis数据库之间的同步,比如双写策略或异步补偿机制。这部分需要详细说明,因为这是后端使用Redis时常见的挑战。 最后,总结最佳实践常见误区,帮助用户避免典型错误,如缓存穿透、雪崩等,并提供解决方案如布隆过滤器或合理过期时间设置。这样用户能全面了解如何有效利用Redis提升后端性能。</think>### 后端开发中 Redis 的 7 大核心使用场景与技术实现 Redis 在后端系统中主要用于 **高性能缓存**、**分布式协调** **实时数据处理**,以下是具体使用方式代码示例: --- #### 一、基础环境搭建(以 Java SpringBoot 为例) ```java // 1. 添加依赖(pom.xml) <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> // 2. 配置连接参数(application.yml) spring: redis: host: 127.0.0.1 port: 6379 password: your_password lettuce: pool: max-active: 20 # 连接池配置 ``` --- #### 二、高频使用场景详解 ##### 1. 缓存数据加速查询(缓存穿透/雪崩防御) ```java // 查询商品详情(缓存示例) public Product getProduct(String id) { String key = "product:" + id; // 先查缓存 Product product = redisTemplate.opsForValue().get(key); if (product == null) { // 缓存未命中,查数据库 product = db.query("SELECT * FROM products WHERE id = ?", id); // 空值缓存防穿透(设置短过期时间redisTemplate.opsForValue().set(key, product != null ? product : "NULL", 30, TimeUnit.SECONDS); } return "NULL".equals(product) ? null : product; } ``` **优化技巧**: - 使用 **布隆过滤器** 拦截无效查询(RedisBloom 模块) - 热点数据永不过期 + 后台异步更新 --- ##### 2. 分布式会话管理(替代 Cookie/Session) ```java // 用户登录时生成令牌 String token = UUID.randomUUID().toString(); // 存储用户会话数据(Hash 结构更高效) redisTemplate.opsForHash().putAll("session:" + token, Map.of("userId", "1001", "role", "admin")); // 设置 30 分钟过期 redisTemplate.expire("session:" + token, 30, TimeUnit.MINUTES); ``` --- ##### 3. 分布式锁控制(Redlock 算法) ```java // 加锁(使用 Lua 脚本保证原子性) String lockKey = "lock:order:1001"; String requestId = UUID.randomUUID().toString(); Boolean locked = redisTemplate.execute(script, Collections.singletonList(lockKey), requestId, "30000"); // 解锁(需校验请求ID) String unlockScript = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; redisTemplate.execute(unlockScript, Collections.singletonList(lockKey), requestId); ``` --- ##### 4. 排行榜实时计算(Sorted Set) ```python # 用户得分更新(Python示例) r = redis.Redis() # 添加/更新分数 r.zadd("leaderboard", {"user_1001": 1500, "user_1002": 1200}) # 获取TOP10 top10 = r.zrevrange("leaderboard", 0, 9, withscores=True) ``` ```sql -- 对应 SQL 对比(性能差异明显) SELECT user_id, score FROM scores ORDER BY score DESC LIMIT 10; ``` --- ##### 5. 限流控制(滑动窗口算法) ```java // 接口限流(每分钟允许100次) public boolean allowRequest(String apiKey) { String key = "rate_limit:" + apiKey; long now = System.currentTimeMillis(); // 移除1分钟前的记录 redisTemplate.opsForZSet().removeRangeByScore(key, 0, now - 60000); // 添加当前请求 redisTemplate.opsForZSet().add(key, UUID.randomUUID().toString(), now); // 检查当前数量 return redisTemplate.opsForZSet().zCard(key) <= 100; } ``` --- ##### 6. 消息队列(替代 RabbitMQ/Kafka 轻量级方案) ```java // 使用 List 结构实现队列 // 生产者 redisTemplate.opsForList().rightPush("queue:orders", orderJson); // 消费者(阻塞式获取) while (true) { // 超时时间 30 秒 String orderJson = redisTemplate.opsForList().leftPop("queue:orders", 30, TimeUnit.SECONDS); if (orderJson != null) { processOrder(orderJson); } } ``` --- ##### 7. 实时统计(HyperLogLog) ```java // UV 统计(误差率 0.81%) String key = "uv:20231001"; // 添加用户访问记录 redisTemplate.opsForHyperLogLog().add(key, userId); // 获取统计结果 Long uv = redisTemplate.opsForHyperLogLog().size(key); ``` --- #### 三、Redis 使用最佳实践 1. **键命名规范** - 使用 `业务:类型:ID` 格式,如 `user:session:1001` - 避免使用特殊字符(如空格、换行符) 2. **内存优化策略** - 优先使用 `Hash` 替代多个 `String` 存储关联数据 - 对大量小对象使用 `ziplist` 编码(需配置 redis.conf) 3. **持久化选择** ```conf # redis.conf 配置建议 save 900 1 # 15分钟有1次修改则快照 save 300 10 # 5分钟有10次修改 appendonly yes # 开启 AOF appendfsync everysec # 折中持久化性能 ``` --- #### 四、常见问题解决方案 | 问题类型 | 现象 | 解决方案 | |------------------|--------------------------|-----------------------------| | 缓存穿透 | 大量查询不存在的数据 | 空值缓存 + 布隆过滤器 | | 缓存雪崩 | 大量缓存同时过期 | 随机过期时间 + 热点数据永不过期 | | 热 Key 问题 | 单个 Key 访问量过大 | 本地缓存 + Key 分片 | | 大 Key 问题 | 单个 Value 超过 1MB | 数据拆分 + 使用 Hash/List 结构 | --- #### 五、监控与运维关键指标 1. **内存使用率**:超过 80% 需扩容 2. **命中率**:低于 90% 需优化缓存策略 3. **连接数**:超过 maxclients 的 70% 需调整 4. **持久化延迟**:AOF 延迟超过 1 秒需排查 --- ### 总结:后端使用 Redis 的核心逻辑 1. **数据特性匹配**:选择合适的数据结构(如需要排序用 ZSET) 2. **生命周期管理**:合理设置 TTL 避免内存泄漏 3. **原子性保证**:使用 Lua 脚本处理复杂操作 4. **灾备设计**:主从复制 + Sentinel 实现高可用 通过合理应用 Redis,后端系统的 **并发处理能力可提升 3-5 倍**,典型场景下延迟可控制在 5ms 以内。建议配合可视化工具(如 RedisInsight)进行实时监控。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值