PHP - 使用Redis/Memcachedb/Mongodb或其他持久化存储来存储计数器

6

计数器可以是页面浏览量、下载量、投票数等,基本上不是非常“关键”的数据。

存储这些信息的“最佳”方式是什么?Mysql 不是一个好的选择。你们使用什么呢?

4个回答

10

我认为我会选择Redis,因为:

  • Antirediz(他的昵称)正在积极开发Redis。(每当我看到我的 GitHub 仪表板时,他都会提交一些新代码)。现在他正在全职开发Redis,感谢VMware的支持。
  • Redis是最终持久性的,因此性能非常出色(首先只使用快速的内存)。
  • Redis具有原子increment操作,这是您所需的。
  • Redis有很多好的PHP库。 还有一个被编写为C扩展的,因此具有非常好的性能。 Redis网站也概述了这些扩展功能。 其中一些是纯PHP代码(运行速度略慢,但更容易配置)。

毫无疑问,我会选择Redis。我正在进行一种计数排序的操作,在一台20美元、512MB的VPS上每分钟推送30,000个命令。 :) - James Hartig
我们试图使用 Redis 作为计数器系统。Redis 的主要数据存储是 RAM,但我们的数据集太大了,RAM 存储不起作用。像 Tokyo Tyrant 这样的东西可能更好,它不必一直将整个数据集保存在 RAM 中。 - Frank Farmer
一个简单的计数器无法保存在RAM中吗?Twitter几乎将所有活跃的推文存储在内存中。如果您想要性能,我认为您应该花一点钱购买一个内存模块。此外,您可以便宜地获得几个G的RAM。 - Alfred

9

MongoDB在使用upserts的情况下非常适合这种需求。

如果你要存储像这样的东西:

{ "url" : "www.example.com", "pageviews" : 0 }

您可以使用原子操作$inc快速递增页面浏览量。
db.downloads.update({'url' : 'www.example.com'}, {'$inc' : {pageviews : 1}})

如果您使用upserts,更新文档之前无需检查其是否存在。例如,如果您执行以下操作:
db.downloads.update({'url' : 'www.example.com'}, {'$inc' : {pageviews : 1}}, {"upsert" : true})

如果不存在具有网址www.example.com的文档(页面视图设置为1),则将创建该文档;如果已存在,则页面视图将递增。这意味着您不必担心预填充集合。

1
著名的1990年代浏览计数器使用简单文件存储数字。如果您只需要存储一个数字,任何东西都足够了。

2
如果你有任何有意义的流量,将数据写入磁盘文件会存在并发问题。除非你使用文件锁定,但是这样会存在锁争用的风险。像memcached这样的项目出现就有其存在的原因。 - Frank Farmer
2
但如果您只是在简单的(低流量)站点上使用它,这可能是可行的,并且很容易实现。 - Alfred
锁争用并不难。像这样简单的代码 while(!get_lock() || count > 10000) { sleep(0.001); count++ }; fread() or fwrite(); remove_lock(); 可以轻松处理每秒数十万个请求……前提是你选择的操作系统在文件系统操作上很快。 - Abhi Beckert

-1
我会说APC或memcached是不错的选择。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接