在高流量Web应用程序中记录页面视图的最佳解决方案

时间:2014-05-07 22:44:51

标签: php mysql web statistics

我正在为利基行业建立一个基于网络的目录。我想在每个列表/个人资料上提供一个观看柜台,类似于MySpace在过去的好时光中使用它的方式(回到90年代的MySpace,一切都被原谅)。

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

另一个帖子(What is the best way to count page views in 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年的日期,我想知道从那时起是否有任何更好的解决方案被曝光。

2 个答案:

答案 0 :(得分:2)

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

使用采样率肯定会有助于提高性能,但会降低较低音量的准确度,尤其是100的采样率。也许您可以在低计数时降低采样率。例如对于前1000个页面视图,跟踪每个视图(禁用采样)。之后使用100的采样率。不要通过查找mysql中的计数来执行此操作。在调用异步跟踪脚本时,您需要通过浏览量计数(或等效采样率)。

如果posts表中有大量记录,WHERE查找将增加开销。考虑在另一个专用跟踪表中插入跟踪记录。然后,您可以定期(每晚)通过汇总所有跟踪记录来更新posts.views。

您还可以考虑定期处理和聚合Web服务器日志的方法。这可能特别有效,因为您可能无论如何都要记录所有页面视图。

答案 1 :(得分:0)

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

它比你提到的方法慢,但它比为每个页面视图更新存储在数据库中的计数器更快,特别是在具有多个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 
}