0

我们有一个消息应用程序,它维护一个未读/已读计数器。目前,我们将此值缓存一小时,如果用户点击应用程序并且缓存已过期,则会对数据库表进行计数以刷新缓存值。

问题是当大量用户同时访问并且缓存过期时,这实际上很常见,这给数据库带来了巨大的压力,需要同时实时进行所有计数。

我想找到一种方法来在我们添加或删除消息时在缓存中主动维护这个计数器,这样用户只会点击缓存的值并且它永远不会过期。新问题在于确保计数值保持同步,因为添加或删除会触发缓存更新的消息的系统可能会错过一些,因此这两个数字将不再同步。

我提出的一些选项:

  • 每 X 更新一次强制刷新。这对活跃用户来说很好,但不太活跃的用户更有可能有不准确的计数,并且没有缓存到期,该计数会保留很长时间。

  • 有一个更新计数的后台作业。这样做的问题是它将数据库资源花费在非活动用户上,这是低效且耗时的。

有没有人对这种类型的计数维护有任何一般性建议?

4

1 回答 1

3

我不是 100% 确定您拥有的应用程序,但是如果我假设您有类似邮件客户端的东西,其中您收到的消息数量和发送的消息数量,那么我有一些想法:

  1. 查看 Thundering Herd 关于缓存的想法: http ://en.wikipedia.org/wiki/Thundering_herd_problem 这个想法是您并不总是使用相同的缓存过期值。引入一些随机性。有些会在 1 小时后过期,有些会在 58 分钟后过期,有些会在 1 小时 2 分钟后过期。这可以防止很多东西同时过期。

  2. 考虑使写入端的缓存无效。换句话说,假设我向某人发送消息。当我在 UI 中发送它时,代码应该使其他用户缓存无效(他们接收的计数刚刚增加 1),然后重新填充该值。换句话说,不要只是通过一个应用程序调用使缓存无效。使其无效主动将新值放入缓存中。

  3. 您可以按计划播种缓存,但就像您说的那样,您将做不必要的工作。

  4. 我注意到很多大公司都在处理这样的问题并将它们推到 UI 上。你允许在一段时间内稍微不一致的数据,或者你做一些小把戏。例如,当他们发送消息时,如果您希望它“感觉”快,只需使用 Javascript(假设是 Web 应用程序)将其“发送”计数器增加 1,即使该计数器尚未保存到数据库中。

换句话说,在 UI 中提供即时反馈并稍作修改,然后异步写入数据并等待它完成写入/缓存更新。

于 2013-01-17T18:15:37.390 回答