geo哈希数据无专用淘汰策略,其淘汰行为完全取决于zset key是否设置ttl及所选maxmemory-policy类型;关键配置是maxmemory和maxmemory-policy,且需匹配key生命周期管理方式。

Geo 哈希数据本身没有特殊淘汰逻辑,它只是 zset 的一种用法;配置淘汰规则的关键不是“针对 Geo”,而是看这些 zset key 是否带过期时间、是否允许被删、访问模式是否集中——和普通缓存完全一致。
为什么不能单独为 Geo 设置淘汰策略
Redis 没有 “geo-specific” 淘汰策略。所有地理数据(如用 GEOADD 写入的)底层都存为 zset,而淘汰策略作用于整个 key,不识别 value 类型。你无法告诉 Redis:“只对 zset 里带经纬度的 key 用 TTL 淘汰”。
-
GEOADD不支持直接设过期时间,必须额外调用EXPIRE或PEXPIRE才能给 geo key 加 TTL - 如果没加 TTL,它就和一个普通永久
zset无异,在volatile-*策略下完全不会进入淘汰池 - 即使加了 TTL,Redis 也只认 key 级别的过期标记,不解析其内部是否存了地理坐标
Geo 数据该配 allkeys-lru 还是 volatile-lru
取决于你如何管理生命周期:是否所有 geo key 都明确设置了过期时间?
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 如果你统一用
EXPIRE my:geo:users 3600给每个 geo key 设 TTL → 选volatile-lru更安全:永久配置类 key(如city_boundaries)不会被误删 - 如果你没设 TTL,或只给部分 key 设了(比如用户位置实时更新,但城市边界永不过期)→
volatile-lru会退化成noeviction:没过期 key 可淘汰,内存持续涨,最终写入报(error) OOM command not allowed when used memory > 'maxmemory' - 如果你确认所有 geo 数据都是临时缓存(如附近商家、实时轨迹点),且可全部丢 → 直接用
allkeys-lru,更简单可靠
容易踩的坑:大 zset + LRU 淘汰效率低
Geo 查询常依赖 GEORADIUS,它底层遍历 zset 的 score 范围;而 allkeys-lru 淘汰时,Redis 对 zset 的 LRU 更新开销比 string 高——尤其当单个 geo key 存了几十万点(如某城市所有 POI),lru 字段更新和采样淘汰都会变慢。
- 避免单 key 存海量 geo 点;考虑按区域分片,例如
geo:shanghai:poi、geo:shanghai:user_active - 检查是否存在超大
zset:redis-cli --bigkeys | grep zset,重点关注 size > 10k 的 key - 若必须存大 zset,且访问有强局部性(比如用户总查自己所在区),
allkeys-lfu可能比allkeys-lru更稳——但需确保 Redis ≥ 4.0,且业务访问频次已稳定(LFU 初期易误杀新点)
真正要盯住的配置项只有两个
其他全是干扰项。只要这两个没设对,淘汰策略就是摆设:
-
maxmemory必须显式设置(如2gb),默认0表示不限制,此时任何maxmemory-policy都不触发 -
maxmemory-policy必须匹配你的 key 生命周期管理方式;别只看名字里的 “LRU”,先看前缀allkeys-还是volatile-——这决定了它动不动你那些没设 TTL 的 geo 边界数据
最常被忽略的是:加了 EXPIRE 不等于“自动受控”,还要看策略是否允许淘汰带 TTL 的 key;而没加 EXPIRE 却用了 volatile-*,等于给自己埋了个静默内存泄漏。










