【发布时间】:2010-12-04 20:23:59
【问题描述】:
我想编写一个点击计数器脚本来跟踪网站上图片的点击和原始 IP。每天的展示次数超过数十万,因此计数器每秒会增加很多次。
我正在寻找一种简单的自托管方法(php、python 脚本等)。我正在考虑使用 MySQL 来跟踪这一点,但我猜有一种更有效的方法。有什么好的保持计数器的方法?
【问题讨论】:
我想编写一个点击计数器脚本来跟踪网站上图片的点击和原始 IP。每天的展示次数超过数十万,因此计数器每秒会增加很多次。
我正在寻找一种简单的自托管方法(php、python 脚本等)。我正在考虑使用 MySQL 来跟踪这一点,但我猜有一种更有效的方法。有什么好的保持计数器的方法?
【问题讨论】:
一个引人入胜的主题。增加一个计数器,尽管它可能很简单,只是 必须 是一个事务...意思是,它可以锁定整个数据库比有意义的时间更长!-) 它很容易成为瓶颈整个系统。
如果您需要严格准确的计数但不需要它们立即更新,我最喜欢的方法是将可计数信息附加到日志中(根据需要经常切换日志以达到数据新鲜度的目的)。一旦日志关闭(其中包含数千个可计数的事件),脚本就可以读取它并更新单个事务中所需的所有内容 - 可能不直观,但比数千个单个锁要快得多。
还有一些非常快的计数器,它们仅在统计上是准确的——但既然你没有说这种不精确是可以接受的,我不打算更深入地解释它们。 p>
【讨论】:
您可以获取您的网络服务器的访问日志(Apache:access.log)并一次又一次地评估它(cronjob),以防您不需要在确切时刻手头的数据有人访问您的网站的时间。
通常,无论如何都会生成 access.log,其中包含请求的资源以及时间、日期和用户的 IP。这样您就不必通过 php 脚本来路由所有流量。精益,意味着计数机。
【讨论】:
毫无疑问,Redis 非常适合解决这个问题。它需要大约一分钟的时间来设置和安装,支持原子增量,速度非常快,有用于 python 和 php(以及许多其他语言)的客户端库,是持久的(快照、日志、复制)。
将每个计数器存储到自己的密钥中。那就干脆
INCR key
【讨论】:
有两种非常简单的方法:
选项 1 适用于现成的工具。选项 2 只需要一点编程,但可以让您更接近实时更新,而不会导致您在流量高峰时摔倒(例如您会在直接 mysql 案例中发现)。
【讨论】:
如果准确性很重要,您可以使用 MySql 稍微慢一些...创建一个 HEAP / 内存表来存储您的计数器值。这些内存表非常快。您可以每隔一段时间将数据写入普通表。
根据应用引擎的想法,您可以使用 memcache 作为计数器的临时存储。增加内存缓存计数器比使用 MySql 堆表(我认为)要快。每五或十秒一次,您可以读取内存缓存计数器并将该数字写入您的数据库。
【讨论】:
不确定它是否适合您,但 AppEngine 是一个非常不错的构建平台。此处描述了一些可用于使用其 DataStore 和事务构建计数器的示例代码:http://code.google.com/appengine/docs/python/datastore/transactions.html。
【讨论】:
您可以使用Redis - 它是非常快速的键值存储,支持原子增量。如果需要 - 计数数据可以轻松地在多个服务器之间拆分。
【讨论】:
我做过非常相似的事情,规模相似(多台服务器、数百个域、每小时数千次点击),日志文件分析绝对是要走的路。 (它还检查命中率,按文件类型对它们进行加权,如果它们发出过多的请求,则在防火墙上将 IP 地址列入黑名单;它的预期目的是自动阻止坏机器人,不仅仅是一个计数器,而是计数它的重要组成部分。)
对网络服务器进程本身没有性能影响,因为它没有在那里做任何额外的工作,而且您可以通过每分钟/5 分钟/100 次点击/其他任何情况将定期更新的点击计数注入网站的数据库来轻松发布每次点击都必须锁定相关的行/表/数据库(取决于使用的锁定机制)。
【讨论】:
tail -f 类型的监视器,该监视器在文件写入时从文件中读取(只需注意日志轮换)。
好吧,如果你碰巧走 PHP 路线,你可以使用 SQLite 数据库,但是 MySQL 是存储该信息的一种完全合理的方式,通常(至少从我所见)是如何完成的.
如果您不想将 IP 地址和任何其他信息存储在一个简单的数字 文本文件可以工作。
【讨论】: