网站seo查询站长之家,刷排名seo,物业管理系统和物业管理软件,极客网站建设在 Redis 中#xff0c;设置了过期时间的键在过期时间到达后#xff0c;并不会立即从内存中删除。如果不是#xff0c;那过期后到底什么时候被删除呢#xff1f;
下面对这三种删除策略进行具体分析。
立即删除#xff1a;
立即删除能够保证内存数据的及时性和空间的有效…在 Redis 中设置了过期时间的键在过期时间到达后并不会立即从内存中删除。如果不是那过期后到底什么时候被删除呢
下面对这三种删除策略进行具体分析。
立即删除
立即删除能够保证内存数据的及时性和空间的有效利用但在处理大量过期键时它可能会对系统性能产生负面影响。
优点
立即删除确保过期键在其过期后立即从内存中删除这样可以确保数据的最大新鲜度避免了过期数据继续占用内存。内存释放也是立即删除的一个重要优点因为删除过期键会立即释放其占用的内存空间使得系统能够更有效地管理内存。
缺点
立即删除操作会占用 CPU 时间特别是在处理大量键时或者在 CPU 负载高的情况下。这可能会对同时进行的其他计算任务如交集计算或排序造成额外的压力。这种情况下Redis 可能会在处理删除操作时对其他请求的响应速度产生一定的影响尤其是在高并发情况下。Redis 使用无序链表来管理设置了过期时间的键。这意味着在执行过期键的检查和删除时时间复杂度为 O(n)其中 n 是设置了过期时间的键的数量。尽管时间复杂度为 O(n)但通常情况下链表中的过期键数量不会非常大因此 Redis 的性能通常仍然能够满足大多数实际需求。
综上所述虽然立即删除能够提供数据的最大新鲜度和内存的即时释放但在处理大量过期键时可能会对 CPU 产生较大的负载。
惰性删除
惰性删除是指当一个键过期后如果客户端尝试访问这个键Redis 会先检查键是否过期。如果过期了Redis 不会立即删除它而是返回一个空值nil或者特定的过期标记表示键已经过期。当有客户端访问这个键时Redis 才会删除它并释放内存空间。
所以惰性删除的缺点很明显:浪费内存。dict字典和expires字典都要保存这个键值的信息。特别是在处理像日志这样的按时间更新的数据时它可能会导致内存浪费问题。
定时删除volatile-ttl
定时删除是指Redis 会以一定的频率默认每秒钟检查10次执行定期删除操作。在定期删除过程中Redis 会扫描数据库中的部分过期键并删除其中的过期键。这样做可以及时释放内存空间避免过多过期键导致的内存浪费。
定时删除是一个常见的折中方案能够有效地平衡立即删除和惰性删除所带来的问题。
这种方法通过周期性地执行删除操作来管理过期数据具有以下几个关键优势
控制CPU消耗定时删除可以通过限制每次删除操作执行的时长和频率从而减少对CPU的瞬时负载影响。相比于立即删除它在执行删除操作时分摊了处理压力更加稳定和可控。减少内存浪费相对于惰性删除定时删除能够更及时地清理过期数据从而有效减少长时间未使用的数据占用的内存空间。尤其对于存储大量日志或临时数据的场景这种方式能显著降低内存浪费。可调节性定时删除的执行频率和处理时长可以根据具体应用的需求进行调整。可以根据数据更新频率、过期数据的访问模式以及系统的整体负载情况来动态调整定时删除的策略以达到最佳的性能和资源利用率。实现方式在Redis中可以通过定时任务如使用Cron表达式或者定时执行的后台任务来实现定时删除。也可以结合Redis的过期事件通知功能使得过期数据的清理更加高效和即时。
总之定时删除在实际应用中是一个非常有效的策略特别适用于需要平衡CPU负载和内存利用的场景。通过合理配置删除频率和操作时长可以最大程度地优化系统的整体性能和资源利用效率。
Redis使用的策略
Redis 使用的是一种结合了惰性删除和定期删除的过期键值删除策略这种方式旨在平衡性能和资源利用的效率。
这两种删除策略的结合使得Redis能够在保证内存空间高效利用的同时避免了单次大规模删除操作可能带来的性能问题。惰性删除保证了操作的即时响应性而定期删除则定期清理已过期的键防止过期键占用过多内存。
总结
惰性删除减少了性能开销但可能导致内存浪费。定期删除定期清理过期键平衡性能和内存利用。立即删除实时性高但性能开销大。
springbootRedis的dome
1、引入依赖
首先在 pom.xml 文件中添加 Spring Data Redis 的依赖
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId
/dependency
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId
/dependency2、配置 Redis
在 application.yml文件中配置 Redis 连接
spring:data:redis:host: localhostport: 6379database: 0password: # 密码默认为空
3、配置 RedisTemplate
创建一个配置类来配置 RedisTemplate
package com.example.demo.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;Configuration
public class RedisConfig {/*** 配置 RedisTemplate* 使用 StringRedisSerializer 序列化和反序列化 redis 的 key 值* 使用 GenericJackson2JsonRedisSerializer 序列化和反序列化 redis 的 value 值** param redisConnectionFactory Redis 连接工厂* return 配置好的 RedisTemplate*/Beanpublic RedisTemplateString, Object redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplateString, Object template new RedisTemplate();template.setConnectionFactory(redisConnectionFactory);// 设置 key 和 Hash 的 key 序列化器为 StringRedisSerializertemplate.setKeySerializer(new StringRedisSerializer());template.setHashKeySerializer(new StringRedisSerializer());// 设置 value 和 Hash 的 value 序列化器为 GenericJackson2JsonRedisSerializertemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());// 初始化 RedisTemplatetemplate.afterPropertiesSet();return template;}
}4、使用 Redis 设置键的过期时间
创建一个简单的服务类来处理 Redis 操作
package com.example.demo.service;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;/*** Redis服务类用于处理Redis相关的操作*/
Service
public class RedisService {/*** RedisTemplate用于操作Redis支持各种数据类型的存储和读取*/Autowiredprivate RedisTemplateString, Object redisTemplate;/*** 设置键值对并指定过期时间** param key 键* param value 值* param timeout 过期时间* param unit 过期时间单位*/public void setValueWithExpiration(String key, Object value, long timeout, TimeUnit unit) {redisTemplate.opsForValue().set(key, value, timeout, unit);}/*** 根据键获取值** param key 键* return 对应的值如果不存在返回null*/public Object getValue(String key) {return redisTemplate.opsForValue().get(key);}/*** 删除指定键** param key 要删除的键*/public void deleteValue(String key) {redisTemplate.delete(key);}
}5、创建控制器来测试
创建一个简单的控制器来测试 Redis 过期键
package com.example.demo.controller;import com.example.demo.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.util.concurrent.TimeUnit;/*** Redis控制器用于处理Redis相关的HTTP请求*/
RestController
RequestMapping(/redis)
public class RedisController {/*** 注入Redis服务用于执行Redis操作*/Autowiredprivate RedisService redisService;/*** 设置Redis键值对并指定过期时间** param key 要设置的键* param value 键的值* param timeout 过期时间秒键将在指定秒数后自动删除* return 响应实体包含设置结果的信息*/GetMapping(/set)public ResponseEntityString setKey(RequestParam String key, RequestParam String value, RequestParam long timeout) {redisService.setValueWithExpiration(key, value, timeout, TimeUnit.SECONDS);return ResponseEntity.ok(键已设置并将于 timeout 秒后过期);}/*** 获取Redis中的键值** param key 要获取的键* return 响应实体包含键的值或相应提示信息*/GetMapping(/get)public ResponseEntityObject getKey(RequestParam String key) {Object value redisService.getValue(key);if (value null) {return ResponseEntity.ok(键不存在或已过期);}return ResponseEntity.ok(value);}/*** 删除Redis中的键** param key 要删除的键* return 响应实体包含删除结果的信息*/GetMapping(/delete)public ResponseEntityString deleteKey(RequestParam String key) {redisService.deleteValue(key);return ResponseEntity.ok(键已删除);}
}
6、测试应用程序
启动 Spring Boot 应用程序并通过以下 URL 测试 Redis 过期键
设置键并指定过期时间例如 10 秒http://localhost:8080/redis/set?keytestKeyvaluetestValuetimeout10
响应: 键已设置并将于 10 秒后过期
获取键的值http://localhost:8080/redis/get?keytestKey
如果键存在: 返回键的值如果键不存在或已过期: 键不存在或已过期
删除键http://localhost:8080/redis/delete?keytestKey
响应: 键已删除