在键/值存储和db计数中维护计数器值的技术

时间:2013-01-17 17:16:17

标签: database caching nosql key-value

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

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

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

我提出的一些选项:

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

  • 拥有更新计数的后台作业。这就存在将数据库资源用于非活动用户的问题,这是低效且耗时的。

有没有人对此类计数维护有任何一般性建议?

1 个答案:

答案 0 :(得分:3)

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

  1. 查看Thundering Herd缓存的想法:http://en.wikipedia.org/wiki/Thundering_herd_problem我们的想法是您并不总是使用相同的缓存过期值。介绍一些随机性。有些会在1小时后到期,有些会在58分钟后到期,有些会在1小时2分钟内到期。这可以防止很多事情同时到期。

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

  3. 您可以按计划对缓存进行播种,但就像您说的那样,您正在开展不必要的工作。

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

  5. 换句话说,在UI中提供即时反馈并稍微捏一下,然后异步写入数据并等待它完成写入/缓存更新。