Skip to content

实现二级缓存

数据墙DBW长期以来一直支持一级(L1)内存缓存,以及与缓存相关的 HTTP 请求头(例如 no-storeno-cacheonly-if-cached)来影响缓存行为。

二级(L2)缓存通过添加分布式缓存层,将缓存扩展到本地进程之外。启用 L2 后,缓存结果可以在多个数据墙DBW实例之间复用,并且能够在单个容器重启后继续保留,从而让无状态部署在正确的地方“看起来没那么无状态”。

二级缓存的收益

在以下场景下适合使用二级缓存:

  • 在横向扩展后的多个数据墙DBW实例之间共享缓存结果
  • 减少重复读取操作对数据库的往返请求
  • 在容器回收或重新部署后,仍保持无状态容器的“热启动”体验
  • 提升读多写少工作负载的性能
  • 使用分区来对缓存参与范围做命名空间隔离

配置运行时缓存设置

二级缓存是在 runtime.cache 下做全局配置的。运行时缓存块会启用缓存、设置默认 TTL,并配置分布式缓存提供程序。

json
{
  "runtime": {
    "cache": {
      "enabled": true,
      "ttl-seconds": 30,
      "level-2": {
        "enabled": true,
        "provider": "redis",
        "connection-string": "localhost:6379",
        "partition": "prod-api"
      }
    }
  }
}

运行时属性

属性说明
enabled全局启用缓存支持。
ttl-seconds设置默认缓存生存时间(秒)。
level-2.enabled打开分布式缓存层。
level-2.provider选择分布式缓存提供程序。当前仅支持 redis
level-2.connection-stringRedis 实例的连接字符串。
level-2.partition可选的 Redis 键和 backplane 通道命名空间。只有使用同一分区的容器才会共享同一个分布式缓存空间。

配置实体级缓存行为

实体可以覆盖全局缓存行为。使用实体上的 cache 块启用缓存、设置自定义 TTL,并选择缓存级别。

json
{
  "entities": {
    "Products": {
      "source": "dbo.Products",
      "cache": { "enabled": true, "ttl-seconds": 120, "level": "L1L2" }
    },
    "Orders": {
      "source": "dbo.Orders",
      "cache": { "enabled": true, "level": "L1" }
    }
  }
}

cache.level 属性

使用 cache.level 控制实体要使用哪些缓存层级。

说明
L1仅内存缓存。速度快,并且仅存在于当前数据墙DBW进程内。
L1L2内存缓存加分布式缓存。这是启用缓存实体的默认级别。

如果全局没有启用 L2,那么配置为 L1L2 的实体会退化为 L1 行为。

L1L2 的工作方式

TIP

一句话版本L1L2 = Request -> L1 -> L2 -> database -> L2 -> L1 -> Response

默认情况下,只要实体启用了缓存,就会使用 L1L2 级别。

  • L1 是进程级的内存缓存
  • L2 是分布式缓存层(当前为 Redis),并带有用于跨实例一致性的 backplane

L1L2 模式下,请求会先检查 L1。如果 L1 未命中,则在全局已启用且已正确配置二级缓存时,再检查 L2。如果两个层级都没有命中,数据墙DBW才会执行数据库查询。查询结果随后会同时写入 L1L2

这意味着:

  • 同一实例上的后续请求会直接从本地 L1 命中
  • 其他实例上的请求可以从 L2 读取结果,并把该结果提升到它们自己的 L1
  • 如果某个容器重启,虽然它本地的 L1 会丢失,但只要 L2 命中,仍然可以避免再次访问数据库

这种组合方式为横向扩展或频繁回收的实例提供了一个“温热”的分布式缓存层。

Redis 支持

Redis 是当前二级缓存的实现提供程序。它很适合该场景,因为它支持:

  • 多个数据墙DBW实例之间共享访问
  • 基于 TTL 的键过期机制
  • 高吞吐读写
  • 实例之间的 backplane 协调

分区化缓存空间

使用可选的 partition 设置可隔离分布式缓存活动。数据墙DBW会使用该分区值为 Redis 键和 backplane 通道添加命名空间。只有共享同一个分区值的容器才会参与同一个分布式缓存空间。

在以下情况下,这个设置很有用:

  • 将生产与非生产流量分离
  • 隔离不同租户或不同环境
  • 防止无关服务共享缓存项

另请参阅

数据墙DBW 产品文档与开发指南。