【问题标题】:Is it possible to serve stale data from Redis by design?是否可以通过设计从 Redis 提供陈旧数据?
【发布时间】:2020-05-26 22:21:29
【问题描述】:

我有一个 Java 应用程序,负责为客户端应用程序提供各种(有时很大)json 响应。在应用程序层,它使用 Redis (AWS ElastiCache) 缓存 json,其 TTL 取决于特定请求,从 30 秒到 5 分钟不等。一些请求运行时间相当长(5-15 秒),涉及多个外部服务并返回大量数据。如果 TTL 是 60 秒,那仍然意味着某些用户每分钟都得到不可接受的响应时间。我不想在 TTL 启动时立即从缓存中清除数据,而是想启动一个后台任务来获取数据并刷新缓存,同时继续提供数据的陈旧副本(如果存在)。 Redis 可以做到这一点吗?

【问题讨论】:

  • 您可以将您的 TTL 设置为长于后台任务间隔吗?那么它只会在出现问题时过期。
  • 您是否有理由使用超时,而不是在缓存项目更改时使其失效?
  • @ChrisTanner - 我们无法预测将请求哪些缓存键,因此我们无法运行定期安排的后台任务来保持更新。
  • @TagueGriffith - 我们提供的数据来自许多不同的来源。其中一些我们有能力在它发生变化时得到通知,我们确实设置了一个很长的 TTL 并且只有在我们得到通知时才更新缓存。其他来源更具动态性,我们无法在它发生变化时得到通知,因此我们必须设置一个较低的 TTL(30-60 秒),使其在可接受的范围内以获得良好的用户体验。

标签: java caching redis


【解决方案1】:

您可以通过为要缓存的每个项目编写一对条目来手动实现这一点。

  • item: TTL 设置为硬驱逐的实际项目
  • item/fresh:布尔值,TTL 设置为软驱逐(即标记为过时)。此 TTL 应小于硬 TTL。

查询时,总是要求两个键

场景 1 - 缓存未命中(item 不存在)

  • 从某处获取项目
  • 用两个键填充缓存
  • 退货

场景 2 - 缓存命中(两个键都存在)

  • 退货

场景 3 - 过时(item/fresh 不存在)

  • 在后台创建一个刷新两个键的作业
  • 返回缓存的(陈旧的)项目

【讨论】:

  • 我知道这是一个旧帖子,但是如果我们遇到场景 3,并且我们有大量服务器试图获取该值,并且计算该值需要大量时间,那就是我们很可能会遇到这样一种情况:所有服务器同时运行相同的昂贵后台任务,都试图重新填充缓存。另外,我相信同样可以通过请求密钥的 TTL 来实现,如果剩下的时间少于 X 则刷新它。这实际上将内存占用和所需带宽减半。 (但仍然有同样的问题)。
  • 因为我在这方面发现的信息令人惊讶地少,我只想补充一点,为了安全起见,让第一个想要进行重新验证的服务器执行 GETSET 并在较短的到期时间下解决上述问题,并且仅当缺少该值时,它才会执行后台更新。 (只是抛出想法,以防其他人对此感到困惑)。
猜你喜欢
  • 2014-11-22
  • 2016-05-08
  • 1970-01-01
  • 1970-01-01
  • 2017-10-10
  • 1970-01-01
  • 2017-11-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多