【问题标题】:Redis cache updatingRedis 缓存更新
【发布时间】:2015-10-02 09:19:37
【问题描述】:

EDIT2:澄清:代码已经在未命中逻辑上有刷新缓存。我正在尝试做的是减少错过的缓存命中次数。

我使用 Redis 作为 API 的缓存。这个想法是,当 API 收到调用时,它首先检查缓存,如果数据不在缓存中,API 将获取它并在之后缓存它以备下次使用。

目前配置如下:

maxmemory 50mb
maxmemory-policy allkeys-lru

也就是说,最多使用 50mb 内存,继续尝试其中的密钥,当内存已满时,通过删除最近最少使用的密钥 (lru) 开始。

现在我想介绍第二类键。对于第二类,我将设置一个特定的到期时间。现在我想建立一个机制,当这些密钥过期时,这个机制会启动并刷新它们(并设置新的过期时间)。

我该怎么做?

编辑: 一些进展。事实证明,Redis 有一个发布/订阅消息系统,特别是可以在事件上发送消息。其中之一是过期密钥,可以这样启用:

notify-keyspace-events Ex

我发现这段代码可以描述一个阻塞python process subscribing to Redis' messaging system。它可以很容易地更改为检测密钥过期并在密钥过期时调用 API,然后 API 将刷新密钥。

def work(self, item):
    requests.get('http://apiurl/?q={param}'.format(param=item['data']))

所以这正是我所要求的。

通常,这感觉太危险且无法控制。我可以想象很多不同的情况,在这些情况下这很快就会失败。

那么,有什么更好的解决方案?

【问题讨论】:

  • Keyspace 通知(如 Redis PubSub)不能保证会送达 - 例如,如果您的工作人员断开连接,您将丢失这些消息。我仍然建议您在代码中包含 refresh-catch-on-miss 逻辑。
  • 就像我在其他地方所说的那样,我的代码已经有了 refresh-catch-on-miss 逻辑,而我正在努力避免错过。另外,它是一个缓存:如果通知丢失了,哦,好吧,我们不会刷新那个键,当它丢失时它会被刷新。但希望我们可以避免这种情况。

标签: caching redis


【解决方案1】:

http://redis.io/topics/notifications

Keyspace 通知允许客户端订阅 Pub/Sub 频道 为了接收以某种方式影响 Redis 数据集的事件。 可以接收的事件示例如下:

数据库 0 中所有过期的键。(例如)

...

当为键设置过期时,EXPIRE 会生成过期事件,或者 每次将过期结果设置到密钥时都会发生过期事件 被删除(有关更多信息,请参阅 EXPIRE 文档)。

【讨论】:

  • 我刚刚编辑了我的问题以包含您刚才所说的内容(请检查)。不过感觉有点失控。
  • 因为它是同步的?
  • 我头顶上有几个问题。 A) 如果每个键的 TTL 相同,并且键的数量乘以调用键 key 所需的时间长于 TTL,则此过程永远不会完成,实际上只会建立一个队列。 B)如果太多的密钥碰巧同时过期怎么办?再次排队。
  • Expire 具有恒定的时间(即 O(1))执行。这意味着如果您使大量密钥过期,它将始终在时间阈值以下执行。所以 A) 不会发生。而且我不明白为什么 B) 是一个问题! :)
  • 我知道恒定时间是什么意思,这与我指出的无关:如果密钥存活 1 小时,而我需要 2 小时将它们全部放入内存,那么您看不到问题?这是一个与执行时间无关的大问题。
【解决方案2】:

要使密钥过期,只需使用 Redis 内置的过期机制。您不需要在到期时刷新缓存内容,最简单的方法是在代码遇到缓存未命中时进行。

【讨论】:

  • 这并不能解决我的问题,因为缺少缓存命中正是我想要避免的。
  • 你总会有缓存未命中,除非你的缓存大到足以容纳整个数据库。
猜你喜欢
  • 2018-04-03
  • 2021-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-16
  • 2021-03-10
  • 1970-01-01
相关资源
最近更新 更多