Redis过期删除和缓存淘汰

1. 过期删除

在 Redis 中,键的过期删除机制主要包括惰性删除(Lazy Deletion)和定期删除(Periodic Deletion)。这两种策略有各自的优缺点,Redis 最终会结合这两种方法来管理过期键。

1.1 惰性删除(Lazy Deletion)

机制: 惰性删除策略是指当客户端访问某个键时,Redis会检查该键是否已经过期。如果键已经过期,Redis会立即删除这个键,并返回nil(如果是GET操作)或相应的错误信息。
优点:
1.性能友好: 惰性删除仅在访问键时才会检查是否过期,因此不会额外增加Redis的负担,这种方法对Redis的整体性能影响最小。
2. 实时性: 保证了每次读取时都能返回最新的、未过期的数据,不会读取到已过期的数据。
缺点:
可能的内存浪费: 如果某些键在设置了过期时间后没有被访问过,它们将一直占据内存,直到Redis因内存不足而进行主动清理,这可能导致内存中存在大量无用的过期键,占用宝贵的内存资源。

1.2 定期删除(Periodic Deletion)

机制:
定期删除策略是指 Redis 每隔一段时间会随机抽取一部分设置了过期时间的键,并删除其中已经过期的键。Redis 默认会每 100 毫秒执行一次这样的删除操作,具体实现如下:
Redis 会随机抽取几个数据库(每次处理最多 20 个数据库)。
对于每个选中的数据库,随机选择一定数量的键(通常是 20 个键)。
检查这些键是否已经过期,并删除过期的键。
如果发现过期键的比例超过 25%,Redis 会重复执行上述步骤,以避免内存中存在过多过期键。

优点:
减少内存浪费: 通过定期删除,可以在不访问键的情况下也能清理掉部分过期键,减少内存的占用。
自动清理: 即使某些键没有被访问,定期删除也能确保它们在过期后的一段时间内被清理。

缺点:
非实时性: 定期删除不是实时的,因此有些过期键可能会在过期后的一段时间内仍然存在于内存中,直到下一次定期删除操作才被清理。
性能消耗: 虽然定期删除的频率和强度是可控的,但它仍然会消耗一定的 CPU 资源,特别是在处理大批量键时,可能会影响 Redis 的响应性能。

Redis 实际上结合了惰性删除和定期删除两种策略,以达到在性能和内存使用之间的平衡:

惰性删除 主要用于保证数据的实时性。每次客户端访问键时,Redis 都会检查该键是否过期,如果过期就会立即删除。这种方法确保了客户端永远不会读到过期的数据。

定期删除 主要用于清理那些未被访问的过期键。通过周期性扫描和删除过期键,Redis 避免了这些键占用过多的内存。

2.缓存淘汰

Redis 缓存淘汰策略是在 Redis 达到内存上限时,为了释放内存而删除某些键值对的机制。合理配置缓存淘汰策略对于保证系统的性能和稳定性至关重要。

2.1 背景

Redis 是一个内存数据库,所有数据都存储在内存中。当 Redis 的数据量持续增加并达到内存上限时,无法再添加新的数据。此时,Redis 提供了多种缓存淘汰策略来决定删除哪些数据以腾出空间。

2.2 Redis支持的缓存淘汰策略

Redis 提供了多种缓存淘汰策略,可以通过 maxmemory-policy 配置项进行设置。常见的策略包括:
1.noeviction
描述: 默认策略,不淘汰任何数据。当内存达到上限时,所有可能导致内存增加的写操作都会失败,并返回错误。
适用场景: 适用于希望严格控制内存使用,防止数据丢失的场景。主要用于不适合作为缓存,而是需要持久保存所有数据的场景。
2.allkeys-lru
描述: 在所有键中,使用 LRU(Least Recently Used,最近最少使用)算法淘汰最不常使用的键。
适用场景: 适用于典型的缓存场景,优先保留最近访问的数据,淘汰长时间未访问的冷数据。
3. volatile-lru
描述: 在设置了过期时间的键中,使用 LRU 算法淘汰最不常使用的键。
适用场景: 适用于部分数据需要持久存储,但也希望利用 LRU 算法对设置了过期时间的缓存数据进行淘汰的场景。
4.allkeys-random
描述: 在所有键中随机选择键进行淘汰。
适用场景: 适用于数据访问模式难以预测,所有数据重要性相似的场景。
5.volatile-random
描述: 在设置了过期时间的键中随机选择键进行淘汰。
适用场景: 适用于既要保留部分永久性数据,又希望对可过期数据进行随机淘汰的场景。
6.volatile-ttl
描述: 在设置了过期时间的键中,优先淘汰 TTL(Time to Live,剩余生存时间)值最小的键。
适用场景: 适用于需要根据键的生存时间优先级进行淘汰的场景,如希望尽量保留新近缓存的短期数据。

2.3 LRU 算法的细节

LRU 算法通过追踪每个键的使用情况来判断哪些键是最近最少使用的。Redis 在 LRU 策略下不会对所有键进行严格的 LRU 排序,而是通过近似算法实现。默认情况下,Redis 会采样 5 个键来选择淘汰对象。可以通过 maxmemory-samples 配置项调整采样数量,采样数量越大,LRU 策略越接近最优,但计算开销也会增加。

2.4 最大内存设置

缓存淘汰策略与 Redis 的 maxmemory 设置紧密相关。通过设置 maxmemory,可以限定 Redis 的最大内存使用量,当内存使用达到这个上限时,Redis 就会根据配置的淘汰策略开始删除键值对。
配置示例:

maxmemory 256mb
maxmemory-policy allkeys-lru

2.5 实际应用中的考虑

数据重要性: 如果部分数据非常重要且不应被淘汰,可以选择 volatile-lru 或 volatile-random,以确保无过期时间的键不被淘汰。
访问模式: 如果某些数据访问频率极高,且希望这些数据始终保留在内存中,可以选择 allkeys-lru。
系统性能: 在高并发场景下,合理设置 maxmemory-samples 可以优化 LRU 算法的性能。

2.6 注意事项

防止缓存雪崩: 在高并发情况下,避免所有缓存同时过期导致的缓存雪崩,可以通过设置不同的过期时间来平滑过期。
监控与调整: 定期监控 Redis 的内存使用和命中率,根据业务需求调整 maxmemory 和淘汰策略,确保缓存系统的高效运行。

你可能感兴趣的:(缓存,redis,数据库)