Php 对实时数据表使用Memcached
我的应用程序中有很多数据表(即,数据表可以随时更新,但大多数时候它们显示相同的数据) 其中一些表后面有相当密集的查询,因此每次用户返回页面时,即使没有新的更新,也会再次运行查询 当时我认为Memcached是提高用户性能的理想选择,但我不确定如何实现这一点,因为我对缓存的概念非常陌生 我如何让MySQL告诉Memcached某个查询的结果已经更改,下一次加载时表不应该来自缓存,而是来自数据库,从而更新缓存Php 对实时数据表使用Memcached,php,mysql,caching,memcached,Php,Mysql,Caching,Memcached,我的应用程序中有很多数据表(即,数据表可以随时更新,但大多数时候它们显示相同的数据) 其中一些表后面有相当密集的查询,因此每次用户返回页面时,即使没有新的更新,也会再次运行查询 当时我认为Memcached是提高用户性能的理想选择,但我不确定如何实现这一点,因为我对缓存的概念非常陌生 我如何让MySQL告诉Memcached某个查询的结果已经更改,下一次加载时表不应该来自缓存,而是来自数据库,从而更新缓存 此外,我认为最好只使用新行更新表的数据对象,但我不知道这将是什么过程,因此如果任何人对我的
此外,我认为最好只使用新行更新表的数据对象,但我不知道这将是什么过程,因此如果任何人对我的用例有一些想法,他们将非常感激。这只是一个想法:我认为您可以从MySQL获取数据并将其保存到文件中。然后您可以直接使用这个文件而不是数据库。要更新您的文件,您可以使用许多项目中使用的comet方法,例如facebook使用comet进行通知。可能这是一个选项,可以在有更新时记录。因此,您可以创建一个额外的表,称为update。它应该有两列,优先级和日期时间 每次刷新页面时,您都会通过mysql检查特定优先级的日期时间是否已更改。如果是这样,您知道需要更新该页面上的数据。如果没有,您可以使用当前数据
要使其正常工作,您当然必须在每次数据库更改时更新更新表。这可以手动完成,也可以通过mysql触发器完成。这里有一个通用的答案,可以帮助您完成您想要做的事情: 假设您有
mainpage.php
,其中包含您担心的密集查询。这是假设您已经有一个Memcached对象singleton:
$m = new Memcached();
$m->addServer('localhost', 11211);
在mainpage.php
的某个地方,您可以根据$user\u id
检查缓存结果集:
$data = null;
if($cachedResultSet = $m->get('resultSet'.$user_id))
{
$data = $cachedResultSet;
}
else
{
$data = run_intensive_query($user_id);
$m->set('resultSet'.$user_id, $data);
}
// Then you use $data as long as it's not null
然后,每当作为上述结果集一部分的MySQL表被更新时,您都希望使相关用户的特定缓存记录无效:
$m->delete('resultSet'.$user_id);
这将确保下次加载mainpage.php
时,“过时”结果集将不再存在于缓存中,因此它将检索新结果并适当缓存它们。对于您的问题:
$m->delete('resultSet'.$user_id);
如何让MySQL告诉Memcached某个查询的结果
已更改,并且下次删除时不应从缓存中获取表
是加载的,而不是来自数据库,因此更新
缓存
您需要在数据更新时清除缓存(或等到数据过期)
Memcache是一个密钥存储。。。因此,您需要一个表示要检索的数据的唯一键
例如,假设您有与博客帖子相关的查询。唯一的ID将是您的帖子ID或其页面url/slug
因此,您通常要做的是在数据库中执行查询之前,检查缓存中是否有存储的版本
$memcache = new Memcache();
$memcache->connect('localhost', 11211) or die ("Could not connect");
$postId = 1234; // this would vary between each posts.
$commentsKey = 'comments_'. $postId;
$result = $memcache->get($commentsKey);
if ($result === false) { // key not found
// only fetch when result are NOT in cache
$pdo = new PDO();
$stmt = $pdo->query("SELECT * FROM comments WHERE postId=". $pdo->quote($postId));
$result = $pdo->fetchAll();
// store it for next time
$memcache->set($commentsKey, $result);
} //if
// use result either from cache or database
foreach ($result as $comment) {
// do something with data
}
此外,要重置缓存(或使其无效),您可以在有人发布新注释时清除注释键
$memcache = new Memcache();
$memcache->connect('localhost', 11211) or die ("Could not connect");
$postId = 1234; // this would vary between each posts.
$commentsKey = 'comments_'. $postId;
$memcache->delete($commentsKey);
// OR
$memcache->set($commentsKey, false);
这样,下次用户检索评论时,它将不得不从数据库而不是缓存中提取评论,因为$result将为false。这是个好主意,但可能会变得复杂,因为我有许多用户在使用我的系统。因此,我只想在“属于”用户的行发生更改时发出更新。您可以使用用户ID而不是类别。所以每个用户都有自己的更新时间。不久前,我在NodeJS中尝试了同样的方法。MySQL查询缓存已经可以缓存查询的结果集了。但是,只要更新表,缓存的结果集就会失效。所以,我想使用Memcached缓存特定的结果集仍然有一个很好的用例。您是否使用了一个可能有用于Memcached的API的框架?如果您使用的是Laravel框架,那么这个问题将很容易解决。不过,为了一般地回答您的问题,您需要使用每个用户的唯一密钥(可能是与user_id连接的某个值)缓存特定的结果集。如果存在特定用户的缓存记录,则将从缓存加载。否则,您将运行查询并缓存结果集。然后,对于负责更新主查询中使用的任何表的任何页面,您将使用基于用户id的唯一键使缓存记录无效。