跳到主要内容

LevelDB 做本地缓存时,我会额外补上一层过期策略

· 阅读需 3 分钟
一介布衣
全栈开发者

第一次把 LevelDB 用进项目时,很容易被它的简单和直接打动:本地 KV、读写快、嵌入式、不用额外起服务。可也正因为它太像一个“很方便的本地抽屉”,很多人会自然把它当缓存来用,然后默认它应该顺便帮你解决缓存该有的那套问题。

可实际并不是这样。LevelDB 擅长存取,不擅长替你定义“什么时候该失效”。

为什么本地缓存最容易忽视过期

因为它不像 Redis 那样把 TTL 这件事摆在你面前。
文件就在本地,读写也很顺,你会自然觉得“有值就先用”。但只要这份数据跟时间、新鲜度、版本、下游状态有关,过期策略迟早会成为问题。

最常见的症状就是:

  • 本地命中率很高,但数据越来越旧
  • 应用重启后历史缓存全被继续沿用
  • 一旦下游接口结构变化,旧缓存成了隐形炸弹

我通常怎么补这一层

我更倾向把缓存值和元信息一起存,而不是只存业务数据。
至少会带上:

  • 写入时间
  • 数据版本
  • 命中来源或生成条件

这样读取时就不只是“有没有”,而是还能判断“该不该继续用”。

过期策略不一定只有一种

有些缓存适合固定 TTL,有些更适合版本驱动失效,还有些需要在应用启动时做一次批量清理。
重点不是选哪一种,而是不要假设底层 KV 存储会自动替你做决定。

在 LevelDB 场景里,缓存语义是业务层补出来的,不是数据库层白送的。

为什么我反而喜欢自己补

因为这会逼着你更明确地回答几个问题:

  • 这份数据旧一点能不能接受
  • 多久算旧
  • 数据结构升级时怎么兼容
  • 本地命中失败后是否允许回源重建

这些问题想清楚以后,缓存才真的可控。

小结

LevelDB 作为本地存储工具很好用,但如果把它直接等同于“已经拥有成熟缓存能力”,后面很容易吃亏。
我后来每次把它用在缓存场景里,都会主动再补一层过期和版本语义。多做这一步,本地缓存才不至于从加速器变成隐患。