7

我想编写一个命中计数器脚本来跟踪网站上图像的命中和原始 IP。每天的展示次数超过数十万,因此计数器每秒会增加很多次。

我正在寻找一种简单的自托管方法(php、python 脚本等)。我正在考虑使用 MySQL 来跟踪这一点,但我猜有一种更有效的方法。保持柜台的好方法是什么?

4

9 回答 9

7

一个引人入胜的话题。增加一个计数器,尽管它可能很简单,但它必须一个事务......意思是,它可以锁定整个数据库超过有意义的时间!-)它很容易成为整个系统的瓶颈。

如果您需要严格准确的计数但不需要它们立即更新,我最喜欢的方法是将可计数信息附加到日志中(根据需要经常切换日志以达到数据新鲜度的目的)。一旦关闭日志(其中包含数千个可数事件),脚本就可以读取它并更新单个事务中所需的所有内容 - 可能不直观,但比数千个单个锁要快得多。

还有一些仅在统计上准确的极快计数器——但既然你没有说这种不精确是可以接受的,我不打算更深入地解释它们。

于 2009-10-08T02:28:22.487 回答
4

您可以获取您的网络服务器的访问日志(Apache:access.log)并一次又一次地评估它(cronjob),以防您不需要在有人访问您的网站时及时掌握数据。

通常,无论如何都会生成 access.log 并包含请求的资源以及时间、日期和用户的 IP。这样您就不必通过 php 脚本来路由所有流量。精益,意思是数数机。

于 2009-10-08T06:59:13.580 回答
3

Without a doubt, Redis is perfect for this problem. It requires about a minute to setup and install, supports atomic increments, is incredibly fast, has client libs for python and php (and many other languages), is durable (snapshots, journal, replication).

Store each counter to its own key. Then simply

INCR key
于 2010-01-08T13:41:57.647 回答
2

有两种非常简单的方法:

  1. 从您的网络日志中批量解析它。
  2. 通过beanstalkdgearmand运行命中,并让工人以受控的方式完成困难的工作。

选项 1 适用于现成的工具。选项 2 只需要一点编程,但会给你一些更接近实时更新的东西,而不会导致你在流量高峰时摔倒(比如你会在你的直接 mysql 案例中找到)。

于 2009-10-08T03:06:30.530 回答
1

如果准确性很重要,您可以使用 MySql 稍微慢一点...创建一个 HEAP / 内存表来存储您的计数器值。这些内存表非常快。您可以每隔一段时间将数据写入普通表。

根据应用引擎的想法,您可以使用 memcache 作为计数器的临时存储。增加内存缓存计数器比使用 MySql 堆表(我认为)要快。每五或十秒一次,您可以读取 memcache 计数器并将该数字写入您的数据库。

于 2009-10-08T05:34:53.453 回答
0

您可以使用Redis - 它是非常快速的键值存储,支持原子增量。如果需要 - 计数数据可以轻松地在多个服务器之间拆分。

于 2009-12-14T11:05:42.893 回答
0

我做过非常相似的事情,规模相似(多台服务器,数百个域,每小时数千次点击),日志文件分析绝对是要走的路。(它还检查命中率,按文件类型对它们进行加权,如果它们发出过多请求,则在防火墙上将 IP 地址列入黑名单;它的预期目的是自动阻止坏机器人,不仅仅是一个计数器,而是计数它的重要组成部分。)

对 Web 服务器进程本身没有性能影响,因为它没有在那里做任何额外的工作,您可以通过每分钟/5 分钟/100 次点击/任何时间将定期更新的点击计数注入站点的数据库来轻松发布它们,而无需锁定每次命中时相关的行/表/数据库(取决于使用的锁定机制)。

于 2009-12-14T11:21:55.353 回答
0

不确定它是否适合您,但 AppEngine 是一个非常好的构建平台。此处描述了可用于使用其 DataStore 和事务构建计数器的一些示例代码:http ://code.google.com/appengine/docs/python/datastore/transactions.html 。

于 2009-10-08T03:09:43.550 回答
-1

好吧,如果您碰巧走 PHP 路线,您可以使用SQLite数据库,但是 MySQL 是存储该信息的一种完全合理的方式,并且通常(至少从我所见)是如何完成的。

如果您不想存储 IP 地址和任何其他信息,则可以在文本文件中使用简单的数字。

于 2009-10-08T02:25:42.960 回答