如何使用 redis 缓存更新页面计数器?



为了提高我的应用程序的性能,我想尽可能避免访问数据库。因此,要更新页面访问计数器,我想使用 redis 缓存,它能够使密钥过期。

有数千个页面,每个页面每秒可以访问几次。

这是我所想的伪代码:

- Define key: `pagetimer:<id>` as timer, which expires after 10 minutes 
- Define key: `page:<id>:<visits>` as the page.visits counter 
- After each page visit, If `pagetimer:<id>` exits: 
page:<id>:<visits>++
else: 
//`pagetimer:<id>` has expired so:
flush page:<id>:<visits> value to database's page.visits
define new pagetimer:<id>` 
set page:<id>:<visits> to the value obtained from database's page.visits
page:<id>:<visits> ++

我想知道这种策略可能有什么缺陷?是否有更好的解决方案?

这种策略的缺陷可能是什么

它具有以下缺陷:

  • 您的代码不是原子的,并且具有争用条件。因此,您可能会丢失一些访问计数,并且可能会比您想要的更多地访问数据库。

  • 如果你试图使代码原子化,例如使用事务或Lua脚本,你会遇到性能问题:当你读取或写入数据库时,它会阻止Redis。

  • 如果在计时器过期后从未访问过某个页面,则计数器将不会刷新到数据库。

是否有更好的解决方案

是的,有。但是,它要复杂得多,需要解决上述问题。我会给你一些打击。

  • 您需要为每个页面设置多个计数器,例如,每 10 分钟或每 1000 次计数创建一个新计数器。

  • 您需要在另一个线程或进程中更新数据库。

最新更新