1

我有一个 PHP 脚本,它显示了通过 JQuery AJAX 调用为锦标赛评分网站加载的多个数据表。这些表格是实时计算的个人和团队得分。

每分钟检查一次每个表的新分数,并在需要时刷新。为此,每个表都会向分数的最后更新时间发送一个快速 ajax 请求......如果时间与表当前的时间不同,则用新数据刷新表。

我的问题是这些锦标赛可能会变得非常大,有许多参与者、团队、部门和分数,并且加载每个表都使用服务器资源。如果少数人正在查看实时统计数据,这没有问题,但是一旦超过 50 人连接到此统计数据页面,服务器就会开始严重滞后。

我想知道我可以做些什么来优化数据、ajax 调用或服务器本身以尽可能高效地运行,这样服务器就不会那么快达到顶峰。我已经梳理了 MySQL 调用,并尝试尽可能优化所有内容,但这似乎还不够。

任何想法将不胜感激!

4

2 回答 2

1

您可以使用缓存,例如在您的架构中 memcache 非常适合。每次您的服务器收到请求时,您的 php 应用程序都会尝试从缓存中获取结果,如果未找到则执行查询。

现在您可以选择两种不同的方式:

  • 简单,等待缓存过期时间。当缓存过期时,服务器会错过搜索并提交新的查询。这通常是一个短期缓存(秒或分钟)
  • hard,缓存在很远的将来过期,例如几小时甚至几天)。在这种情况下,您的应用程序会在每次更新数据库时刷新缓存内容。在这种情况下,很明显,几乎所有请求都命中了缓存(最佳性能)。

此示例基于简单方法,缓存键直接基于提交的 SQL。

global $memcache;
$memcache = new Memcache;

// Gets key / value pair into memcache ... called by mysql_query_cache()
function getCache($key) {
    global $memcache;
    return ($memcache) ? $memcache->get($key) : false;
}

// Puts key / value pair into memcache ... called by mysql_query_cache()
function setCache($key,$object,$timeout = 60) {
    global $memcache;
    return ($memcache) ? $memcache->set($key,$object,MEMCACHE_COMPRESSED,$timeout) : false;
}

// Caching version of mysql_query()
function mysql_query_cache($sql,$linkIdentifier = false,$timeout = 60) {
    if (($cache = getCache(md5("mysql_query" . $sql))) !== false) {
        $cache = false;
        $r = ($linkIdentifier !== false) ? mysql_query($sql,$linkIdentifier) : mysql_query($sql);
        if (is_resource($r) && (($rows = mysql_num_rows($r)) !== 0)) {
            for ($i=0;$i<$rows;$i++) {
                $fields = mysql_num_fields($r);
                $row = mysql_fetch_array($r);
                for ($j=0;$j<$fields;$j++) {
                    if ($i === 0) {
                        $columns[$j] = mysql_field_name($r,$j);
                    }
                    $cache[$i][$columns[$j]] = $row[$j];
                }
            }
            if (!setCache(md5("mysql_query" . $sql),$cache,$timeout)) {
                // If we get here, there isn't a memcache daemon running or responding
            }
        }
    }
    return $cache;
}

于 2012-12-02T23:30:52.057 回答
1

缓存输出,每 1 或 5 分钟,刷新缓存...

所以我的意思是,只需将数据库输出写入文件,然后在那一分钟内的所有请求都使用该文件......每个请求,检查文件的年龄,如果超过 1 或 2 或 5 分钟(示例),删除缓存文件并重建它

这将允许 mysql 在那段时间休息...... Ajax 调用正是需要做的......只要你觉得你的间隔是必要的

一些示例 PHP:

$cache_expires = 2; # Minutes
if (file_exists("stats.cache") && filemtime("stats.cache")>time()-$cache_expires*60) {
  # Read cache
  $result = unserialize(file_get_contents("stats.cache"));
  # Display result
} else {
  # Query the database
  $result = get_stats_from_database();
  # Write cache
  file_put_contents("stats.cache",serialize($result));
  # Display result
}
于 2012-12-02T23:15:56.810 回答