1

我有很多用户在 apache 服务器上轮询我的 php 脚本,他们运行的 mysql 查询是

"SELECT * FROM `table` WHERE `id`>'example number'

示例编号可能因用户而异,但有一个已知的下限,每 10 分钟更新一次。

每个用户每秒都会轮询服务器两次。

可以使用memcache吗?向用户显示最新信息并不重要,如果它落后一秒左右就可以了。

该站点在高峰时段有 200 个并发用户。它非常低效并且耗费大量资源。

4

3 回答 3

1

为了给出准确的答案,我需要更多信息

  1. 查询是否拉取个性化信息。
  2. 轮询请求是否获得了随请求一起提供的“示例编号”。

查看您构建问题的方式,用户似乎没有在轮询任何个性化信息。所以我假设“示例编号”也作为轮询请求的一部分出现。

我同意@roberttstephens 和@Filippos Karapetis,您可以使用理想的解决方案

  1. 雷迪斯
  2. NoSQL
  3. 调整 MySQL
  4. 内存缓存

但是,由于你们已经在野外使用了该应用程序,因此实施上述解决方案将产生成本,因此这些是我推荐的实用解决方案。

  1. 将表的索引添加到相关列。[第一件事要检查/做]
  2. 启用 mysql 查询缓存。
  3. 使用反向代理——例如:varnish。[假设“示例编号”是请求的一部分]

    • 为了在请求到达您的应用程序服务器之前与请求相交,这样 MySQL 查询、MemCache/Redis 查找就不会发生。
    • 确保您在响应中设置了特定的缓存标头,以便 varnish 缓存它。
    • 因此,在 200 个并发请求中,如果其中有 100 个正在查询相同数量的 varnish,则会受到打击。[这与 memcache 可以提供的优势相同]。
    • 实施方面,它在开发/测试工作方面的成本并不高。
    • 我知道这不是确切问题的答案。但我相信这可以解决你的问题。
  4. 如果“示例编号”不是请求的一部分,并且您必须从数据库中获取它[通过查看用户表可能是..]然后@roberttstephens 方法是要走的路。只是为了给你确切的图片,我已经重构了一点代码。`addServer('localhost', 11211);

    $inputNumber = 12345;
    $cacheKey = "poll:".$inputNumber;
    
    $result = $m->get($cacheKey);
    if ($result) {
        return unserialize($result);
    }
    
    $sth = $dbh->prepare("SELECT column1, column2 FROM poll WHERE id = $inputNumber");
    $sth->execute();
    $poll_results = $sth->fetch(PDO::FETCH_OBJ);
    $m->set($cacheKey, serialize($poll_results));`
    
于 2013-06-22T04:44:36.947 回答
0

在我看来,您在这里尝试使用错误的工具来完成这项工作。

memcached 是一个键/值存储,因此您可以使用给定的一组键快速存储和检索多个值。但是,您似乎事先并不知道您想要的键,因为您正在查找 id 大于数字的所有记录而不是 ID 的集合。因此,在我看来,memcached 不适合在您的场景中使用。

以下是您的选择:

选项 1:继续使用 MySQL 并正确调整它

如果您正确调整 MySQL,它会非常快。你可以:

选项 2:使用更高级的键值存储

有 memcached 的替代品,最著名的是redis。redis 确实允许更大的灵活性,但它比 memcached 更复杂。对于您的场景,您可以使用 redis zrange命令来检索您想要的结果 - 查看可用的redis 命令以获取更多信息。

选项 3:使用文档存储 NoSQL 数据库

您可以使用文档存储NoSQL数据库,最著名的例子是MongoDB

您可以在 MongoDB 中使用比在 memcached 中更复杂的查询(例如,使用运算符,如您需要的“大于”)。这是一个如何使用运算符搜索 mongo 集合中的结果的示例(检查示例 2)。

查看PHP MongoDB手册以获取更多信息。

此外,这个 SO question是关于文档存储 NoSQL 数据库的有趣读物。

于 2013-06-22T01:12:05.533 回答
0

您绝对可以使用 memcached 来缓存结果。相反,您可以在 mysql 中轻松创建缓存表。

无论哪种情况,您都需要为缓存创建一个 id,并根据该 id 检索结果。您可以使用 entity_name:entity_id 或 namespace:entity_name:entity_id 之类的东西,或者任何适合您的东西。

请记住,memcached 是服务器上运行的另一项服务。您必须安装它,将其设置为在重新启动时启动(或者至少应该),分配内存等。您还需要 php-memcached。

话虽如此,请查看 memcached 上的 php 文档。http://php.net/manual/en/memcached.set.php。假设您的投票 id 是 12345,您可以像这样使用 memcached。

<?php
// Get your results however you normally would.

$sth = $dbh->prepare("SELECT column1, column2 FROM poll WHERE id = 12345");
$sth->execute();
$poll_results = $sth->fetch(PDO::FETCH_OBJ);

// Set up memcached. It should obviously be installed, configured, and running by now.
$m = new Memcached();
$m->addServer('localhost', 11211);

$m->set('poll:12345', serialize($poll_results));

这个例子没有任何错误检查或任何东西,但这应该解释如何去做。我现在也没有运行 php、mysql 或 memcached 实例,因此上述内容尚未经过测试。

于 2013-06-22T02:11:36.863 回答