腾讯云分布式缓存数据库支持 Redis、Valkey、Memcached 等多种存储引擎,将数据存储在内存中,以实现微秒级的读写响应。但内存资源有限且断电后不可持久化,因此在使用前需明确两个前提:缓存实例应定位为缓存而非持久化数据库,以及必须配置合理的内存淘汰策略来防止内存写满后的服务中断。本文档定义缓存使用的基本准则和内存淘汰策略的选型建议。
一、缓存定位准则
缓存实例仅作为缓存使用。缓存实例将所有数据存储在内存中,访问速度快,但内存在断电后无法持久化保存数据。如果将缓存实例作为持久化数据库使用,有可能导致数据丢失。
二、不唯一数据源准则
缓存实例作为缓存使用时,存在缓存未命中的情况,因此不能作为唯一的数据来源。在调用缓存实例发生异常或缓存未命中时,需要回退查询后台数据库(如 MySQL、PostgreSQL 等),确保业务数据的完整性。
三、Key 淘汰准则
根据业务类型,设置合适的内存淘汰策略
maxmemory-policy。默认策略为 noeviction(不删除任何键),在内存占满后将拒绝所有写入操作并返回 OOM 错误。建议在创建实例后立即修改淘汰策略,避免因内存写满导致服务中断。如何配置参数,请参见 管理实例参数。3.1 淘汰算法说明
缩写 | 全称 | 说明 |
LRU | Least Recently Used | 最近最少使用。记录每个键最近被访问的时间,优先淘汰最久未被访问的键。 |
LFU | Least Frequently Used | 最不经常使用。记录每个键被访问的次数,优先淘汰访问次数最少的键。 |
TTL | Time To Live | 生存时间。衡量键距离过期的剩余时间。 |
3.2 可选的内存淘汰策略
策略 | 作用范围 | 淘汰规则 |
allkeys-lru | 所有键 | 优先淘汰最近最少使用的键,直到腾出足够空间。 |
allkeys-lfu | 所有键 | 优先淘汰访问次数最少的键,直到腾出足够空间。 |
allkeys-random | 所有键 | 随机淘汰键,直到腾出足够空间。 |
volatile-lru | 设置了过期时间的键 | 优先淘汰设置了 TTL 的键中最近最少使用的键。 |
volatile-lfu | 设置了过期时间的键 | 优先淘汰设置了 TTL 的键中访问次数最少的键。 |
volatile-ttl | 设置了过期时间的键 | 优先淘汰 TTL 值较小(即即将过期)的键。若无设置 TTL 的键,回退到 noeviction 策略。 |
volatile-random | 设置了过期时间的键 | 随机淘汰设置了过期时间的键。 |
noeviction | — | 不删除任何数据,拒绝所有写入操作并返回错误信息 "(error) OOM command not allowed when used memory",此时仅响应读操作。 |
3.3 淘汰策略选型建议
说明:
缓存实例本身不建议保存持久化数据,
volatile-lru 仅作为混合场景下的备选方案。场景 | 推荐策略 | 说明 |
作为纯缓存使用(推荐) | allkeys-lru | 所有键均可被淘汰,优先移除最久未访问的键。使用频率最低的键后续命中概率也最低,淘汰后对业务影响最小。 |
部分键需要持久保留 | volatile-lru | 仅淘汰设置了过期时间的键,未设置过期时间的键不受影响。适用于既有缓存数据(设置 TTL)又有配置数据(不设置 TTL)的混合场景。 |
需要精确控制键的生命周期 | volatile-ttl | 优先淘汰即将过期的键,适合对数据时效性有明确要求的场景。 |
正确示例: 在创建实例后,将淘汰策略从默认的
noeviction 修改为 allkeys-lru。# 查看当前淘汰策略CONFIG GET maxmemory-policy# 设置为 allkeys-lruCONFIG SET maxmemory-policy allkeys-lru
反面示例: 以下配置可能导致问题。
配置方式 | 问题说明 |
使用默认的 noeviction 且未修改 | 内存写满后所有写操作被拒绝,返回 OOM 错误,服务写入中断。 |
所有键均未设置 TTL,却使用 volatile-lru | volatile-* 策略仅作用于设置了过期时间的键,若所有键均未设置 TTL,等同于 noeviction,无法释放内存。 |
使用 allkeys-random 处理有优先级的缓存数据 | 随机淘汰不区分访问频率,可能误删高频访问的热点键,导致缓存命中率下降。 |