在高流量的web应用程序中记录页面浏览量的最佳解决方案


Best solution for recording page views in a high traffic web app

我正在为一个利基行业建立一个基于网络的目录。我想在每个列表/配置文件上提供一个视图计数器,类似于MySpace在过去美好的日子里使用的方法(回到90年代的MySpace,一切都可以原谅)。

我正在使用MySQL,想知道记录数据的最好方法是什么。

另一个线程(在PHP/MySQL中计算页面浏览量的最佳方法是什么?)提供了以下解决方案@dorkitude:

$sample_rate = 100;
if(mt_rand(1,$sample_rate) == 1) {
    $query = mysql_query(" UPDATE posts SET views = views + {$sample_rate} WHERE id = '{$id}' ");
    // execute query, etc
}

这是基于概率论的,@Suyash解释为

这背后的一般思想是,理论上,应该需要100次尝试才能达到数字'1' -因此视图计数或多或少是正确的,而不需要经常查询数据库。

这个帖子的日期是2011年,我想知道从那时起是否有更好的解决方案出现。

首先,确保跟踪是异步完成的。在页面呈现期间不要执行跟踪。在页面加载后使用javascript调用跟踪脚本。

使用采样率肯定会有助于性能,但会降低较低体积的准确性,特别是采样率为1/100。也许你可以在低计数时降低采样率。例如,对于前1000个页面视图,跟踪每个视图(禁用采样)。之后使用100的采样率。不要通过在mysql中查找计数来做到这一点。当调用异步跟踪脚本时,您需要通过页面浏览量计数(或等效采样率)。

如果posts表中有大量的记录,WHERE查找将增加开销。考虑在另一个专用跟踪表中插入跟踪记录。然后你可以定期(每晚)更新帖子。查看所有跟踪记录的总和。

你也可以考虑一种方法,定期处理和聚合你的web服务器日志。这可能是特别有效的,因为你可能会记录所有的页面浏览量。

下面的代码与您引用的代码类似,但它不是依赖于概率来更新数据库,而是将计数存储在文件中,并在文件计数器达到一定数量时更新数据库。

它比你提到的方法慢,但它比更新存储在数据库中的计数器为每个页面视图更快,特别是在多个web服务器和单个数据库的设置。

$update_rate = 100;
$file = "/my_counters/page_view_counter_$id";
if(!file_exists($file)) {
    file_put_contents($file,0);
}
$fp = fopen($file,"r+");
//acquire lock on counter file
//increment counter by 1
//if counter is equal to update rate, update count in db
//and reset counter to 0
if(flock($fp, LOCK_EX)) {
    $count = fread($fp, filesize($file));
    if(++$count >= $update_count) {      
        $count = 0;
    }
    rewind($fp);
    fwrite($fp,$count);
    flock($fp,LOCK_UN); //release lock on counter file
}
if($count == 0) {
    $query = mysql_query(" UPDATE posts SET views = views + {$update_rate} WHERE id = '{$id}' ");
    // execute query, etc 
}