Redis 作为高性能的内存数据库在互联网架构中被广泛用作缓存。然而内存资源总是有限的当 Redis 的“零食盒”缓存空间满了就需要根据一定的策略淘汰旧的数据腾出空间给新的数据。如果不加以合理配置就会出现缓存击穿、雪崩等问题影响系统性能甚至稳定性。了解和掌握 Redis 的缓存淘汰策略至关重要。缓存淘汰策略总览Redis 提供了多种缓存淘汰策略通过maxmemory-policy配置项进行设置。常见的策略包括noeviction: 当内存不足以容纳新写入数据时直接返回错误 (OOM)。这是一种最简单粗暴的策略适合对数据完整性要求极高的场景。allkeys-lru: 从所有 key 中淘汰最近最少使用的 (LRU) 数据。这是最常用的策略之一假设最近最少使用的 key 在将来被访问的可能性也最小。volatile-lru: 从设置了过期时间的 key 中淘汰最近最少使用的 (LRU) 数据。这种策略更温和只针对设置了过期时间的 key 进行淘汰。allkeys-random: 从所有 key 中随机淘汰数据。这种策略比较简单但效果往往不如 LRU。volatile-random: 从设置了过期时间的 key 中随机淘汰数据。volatile-ttl: 从设置了过期时间的 key 中选择剩余生存时间 (TTL) 最短的 key 进行淘汰。allkeys-lfu: 从所有 key 中淘汰最近最不经常使用的 (LFU) 数据。LFU 考虑了 key 的访问频率更能反映 key 的重要性。volatile-lfu: 从设置了过期时间的 key 中淘汰最近最不经常使用的 (LFU) 数据。在实际应用中allkeys-lru和volatile-lru是比较常用的选择。如果对数据访问频率有较高要求可以考虑使用allkeys-lfu和volatile-lfu。LRU 和 LFU 算法原理LRU (Least Recently Used)算法的核心思想是如果数据最近没有被访问那么将来被访问的可能性也较小。Redis 实现 LRU 算法时并没有完全按照标准 LRU 算法实现而是采用了一种近似 LRU 算法。它通过在每个 key 的元数据中存储一个 24 位的 counter用来记录 key 的访问时间戳。每次访问 key 时会更新这个 counter。在淘汰数据时Redis 会随机采样一部分 key然后淘汰 counter 值最小的 key。// Redis LRU 算法示例 (简化)int lru_clock get_lru_clock(); // 获取当前 LRU 时钟robj *key find_key_to_evict(); // 随机找到一个 keykey-lru lru_clock; // 更新 key 的 LRU 时钟LFU (Least Frequently Used)算法的核心思想是如果数据最近不经常被访问那么将来被访问的可能性也较小。与 LRU 不同LFU 考虑了 key 的访问频率。Redis 实现 LFU 算法时同样采用了一种近似 LFU 算法。它通过在每个 key 的元数据中存储一个 8 位的 counter用来记录 key 的访问频率。每次访问 key 时counter 会以一定概率递增。在淘汰数据时Redis 会随机采样一部分 key然后淘汰 counter 值最小的 key。// Redis LFU 算法示例 (简化)unsigned char log_counter key-lfu; // 获取 key 的 LFU counterif (random() lfu_decay_time()) { // 模拟时间衰减 log_counter decrement(log_counter); // 降低 counter 值}if (random() lfu_incr_probability()) { // 模拟访问增加频率 log_counter increment(log_counter); // 增加 counter 值}key-lfu log_counter; // 更新 key 的 LFU counter缓存淘汰策略配置与优化配置 Redis 缓存淘汰策略非常简单只需要修改redis.conf文件中的maxmemory-policy配置项即可。例如设置使用allkeys-lru策略# redis.confmaxmemory-policy allkeys-lru也可以通过CONFIG SET命令动态修改配置redis-cli config set maxmemory-policy allkeys-lru除了选择合适的缓存淘汰策略外还可以通过以下方式进行优化合理设置maxmemory: 根据服务器的内存大小和应用的需求合理设置 Redis 的最大内存使用量。避免设置过小导致频繁的淘汰也避免设置过大导致服务器内存不足。设置合理的过期时间: 为 key 设置合理的过期时间避免长期不用的数据占用内存。可以使用EXPIRE命令设置过期时间。使用 Pipeline 批量操作: 减少网络往返次数提高缓存效率。特别是在批量写入数据时使用 Pipeline 可以显著提升性能。监控 Redis 内存使用情况: 使用INFO memory命令监控 Redis 的内存使用情况及时发现和解决内存问题。还可以使用 RedisInsight 等可视化工具进行监控。评估淘汰策略对业务的影响: 在生产环境中需要根据业务特点评估不同淘汰策略对缓存命中率和系统性能的影响。可以使用 A/B 测试等方法进行评估。在高并发场景下Nginx 通常作为反向代理和负载均衡器位于 Redis 前端。合理配置 Nginx 的缓存策略和连接数限制可以进一步提升系统的整体性能。例如可以通过proxy_cache指令启用 Nginx 的缓存功能减轻 Redis 的压力。同时需要根据服务器的硬件配置和应用需求合理设置 Nginx 的worker_processes和worker_connections参数以充分利用服务器的资源。在排查问题时可以使用 Redis 的慢查询日志来定位性能瓶颈。通过分析慢查询日志可以发现执行时间较长的命令并进行优化。例如可以优化查询语句、调整数据结构、使用索引等。总之选择合适的缓存淘汰策略并结合实际情况进行优化才能充分发挥 Redis 的高性能优势保障系统的稳定运行。相关阅读【ROS2学习笔记】分布式通信基于河马优化的LSTM深度学习网络模型(HO-LSTM)的一维时间序列预测算法matlab仿真网络安全等级保护测评实施过程【第五章:计算机视觉-项目实战之生成对抗网络实战】1.对抗生成网络原理-(1)对抗生成网络算法基础知识基本思想、GAN的基本架构、应用场景、标注格式GoFrame框架学习笔记明明是新电脑却越用越卡如何优化