Memcache 和 MySQL 如何协同工作?

22

我正尝试了解(可能部署)memcached 在我们的环境中。

我们有4台运行PHP开发的大型Web应用程序的Web服务器,这些Web服务器通过负载均衡器进行负载均衡。我们已经在使用APC。 我想了解一下memcached是如何工作的。至少,也许我不理解缓存是如何工作的。

我们有一些复杂的动态查询,这些查询将几个表合并以提取数据。每次,数据都来自不同的客户数据库,并且数据不断变化。据我了解,如果一些数据存储在缓存中,并且下次请求相同,则返回相同的数据。(或者我可能完全错了)。

整个memcache(或任何缓存东西)是如何工作的?

3个回答

26

缓存通常是一个非常快速的键/值存储引擎,您可以通过预定的键存储值(通常是序列化的),以便您可以使用相同的键检索存储的值。

与MySQL相关联时,您需要编写应用程序代码,以便在向数据库发出请求之前检查缓存中是否存在数据。如果找到匹配项(存在匹配键),则可以访问与该键关联的数据。目标是尽可能避免向成本更高的数据库发出请求。

以下是示例(仅为演示):

$cache = new Memcached();

$cache->addServer('servername', 11211);

$myCacheKey = 'my_cache_key';

$row = $cache->get($myCacheKey);

if (!$row) {

    // Issue painful query to mysql
    $sql = "SELECT * FROM table WHERE id = :id";

    $dbo->prepare($sql);
    $stmt->bindValue(':id', $someId, PDO::PARAM_INT);

    $row = $stmt->fetch(PDO::FETCH_OBJ);

    $cache->set($myCacheKey, serialize($row));
}

// Now I have access to $row, where I can do what I need to
// And for subsequent calls, the data will be pulled from cache and skip
// the query altogether
var_dump(unserialize($row));

想了解更多信息,请查看PHP文档上的memcached,那里有一些不错的示例和注释。


更具体地说,我有很多在整个应用程序中使用的常量变量。我可以将它们存储在缓存中吗? - Kevin Rave
1
你能给我一个“常量”变量的例子吗?按照定义,常量是不可变的。 - Mike Purcell
1
谢谢!但还有一个问题没有解决。“当数据是动态的时候,不确定要缓存什么以及如何利用它。”显然,即使来自同一张表格的每个结果集,数据也不会相同。 - Kevin Rave
我该使用哪个KEY呢?需要一个数据库来维护KEY清单吗?这是关于XX查询的问题吗? - CodeGuru
不,密钥是根据某种命名约定生成的。例如,如果您要存储用户数据,可以使用类似于"user_data_X"的密钥(其中X是用户ID号码)。您还可以对一些可能存储在缓存中的属性进行哈希处理,以便更轻松地生成缓存密钥。$cacheKey = md5(sprintf('%s_%s', $user->getEmailAddress(), $user->getId()) - Mike Purcell
显示剩余6条评论

2

有几个例子可以说明Memcache的工作原理。 这里 是其中之一。

其次,Memcache 可以与 MySQL 一起使用,也可以独立使用。

它缓存 PHP 中的对象,无论是来自 MySQL 还是其他地方,只要是 PHP 对象,就可以存储在 MemCache 中。

APC 比 Memcache 提供了更多的功能。除了存储 / 缓存 PHP 对象外,它还缓存 PHP 可执行的机器可读操作码,这样您的 PHP 文件就不必经过加载到内存中 ->编译的过程,而是直接从内存中运行已编译的操作码。


谢谢! 但我想我的问题不够清楚。假设这是查询: **SELECT Name, age from Person **code这是结果:codeKrish, 45 Josh, 25 Kevin, 60code`下一次,当我调用相同的查询时,它可能会返回: codeJoe, 45 Jay, 25 Chris, 60 code - Kevin Rave
抱歉重新发布: 谢谢!但我想我的问题不太清楚。假设这是查询: **SELECT Name, age from Person** 这是结果: Krish, 45 Josh, 25 Kevin, 60下一次,当我调用相同的查询时,它可能返回: `Joe, 45 Jay, 25 Chris, 60 ` 这里缓存是如何工作的?查询如何被缓存? - Kevin Rave
2
这个查询无法从您的缓存中回答。缓存假定数据自上次请求以来没有更改。它实际上只是在内存中临时存储一些数据以便快速访问。可以这样看待:如果您刚刚提供了一个请求,要求查看数据库中所有名字以“Kev”开头且年龄大于25岁的人。第一次您的应用程序得到此请求时,必须要求MySQL获取结果。如果您告诉您的应用程序缓存这些结果,下次有人运行完全相同的查询时,它可以直接从缓存中回答。如果数据不同,则无法使用此方法。 - Daan
1
我明白。但是如果结果集每次都在变化,那么我认为缓存就没有任何用处了。 - Kevin Rave

1
如果你的数据在请求之间不断变化,则缓存是毫无意义的,因为那些数据将很快过时。但通常情况下(我敢打赌即使在你的缓存中),对数据库的多个请求会导致相同的数据集,这种情况下,使用内存中的缓存非常有用。
附注:我进行了快速的谷歌搜索,并找到了关于memcached的这个视频,质量相当不错=》http://www.bestechvideos.com/2009/03/21/railslab-scaling-rails-episode-8-memcached。唯一可能的问题是它讲的是Ruby On Rails(我也没怎么用过,但很容易理解)。希望它能帮助你更好地理解这个概念。

非常感谢!这个视频很有帮助! - Kevin Rave

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接