我有一个网站,允许用户通过互相“连接”彼此。该网站需要显示“您有 X 个共同关注者”或“您正在关注 X 个共同关注者”等统计信息。到目前为止,这个计算都是实时处理的,但是现在我们有太多的用户来实时计算这个。
我正在考虑缓存或以其他方式增强此计算的性能的选项,但在我这样做之前,我意识到可能已经存在解决此问题的通用方法,可以在我自己过度设计之前以更简单的方式解决它。
使用的技术:PHP 5.3、MySQL 5.5、nginx 和 Linux 环境。
我假设您不会更改很多地方的朋友列表,也不会经常更改。因此,您有一种在必要时使缓存无效的简单方法。创建一个有 4 行的表:id1, id2, num, date
,并在 id1、id2 和日期上设置索引。现在使用答案中的方法缓存您的数据,但如果您希望发生这种情况,您需要自己删除旧条目。只需添加如下内容:
if rand(1, 100) == 1:
SQL(DELETE FROM cache WHERE date < now - ***)
还要确保 id1 < id2,以避免缓存中的重复。
当用户的好友列表发生变化时,删除所有连接到该用户的缓存条目。这样,您的号码将始终是最新的。
如果您不关心数字是否有点,您的解决方案很好 - 只需标准化 $key,以便 id1 < id2。
我解决这个问题的第一种方法是简单地使用存储在内存中的缓存层(可能使用 memcache)
当用户查看包含这些统计信息的页面时,请检查缓存以查看统计信息是否已存在。如果没有,则计算相互连接的数量并将用户 ID 存储为缓存键的哈希值。
PHP中的示例,有点伪代码:
// Fred = User ID #47, George = User ID #94
$key = md5('47,94');
// Check that cache key is valid
if ($cache->isValid($key)) {
return $cache->get($key);
} else {
// ..calculate mutual connections
$cacheTime = time() + (60 * 60 * 6);
$value = calculateMutualConnections(array(47,94));
$cache->save($key,$value,$cacheTime);
return $value;
}
这会将缓存值存储 6 小时。不确定这是否有足够的时间。我相信这种方法会奏效,但可能不像我想要的那样实时。