1

考虑以下代码:

function getUser($uid) {
    global $_memcache;
    $u = $_memcache->get("user-".$uid);
    if( !$u) {
        $u = ... // get user from database
        $_memcache->set("user-".$uid,$u);
    }
    return $u;
}

现在,这个函数可能会被称为很多。例如,在论坛上,它可能在单个页面加载中被调用 30 多次。是否值得做以下事情,或者 Memcache 是否已经足够优化?

function getUser2($uid) {
    static $localcache = [];
    if( isset($localcache[$uid])) return $localcache[$uid];
    return $localcache[$uid] = getUser($uid);
}
4

2 回答 2

0

嗯,最终 memcached 是在内存存储中,就像在 PHP 数组中存储值一样。如果 memcached 实例位于您运行代码的同一台服务器上,那么我肯定会说只使用 memcached 而不是 memcached 和 PHP 数组,因为您最终会在机器上使用 ~ 两倍的内存将相同的数据存储在内存中两次。

如果 memcached 位于单独的基础架构上(这很可能),那么我想我会考虑为用户存储的数据的大小。如果它很大并且您可能会在 PHP 数组中存储大量用户,这意味着您可能会在 Web 服务器上占用比您认为需要的更多的内存,在这种情况下,从 memcached 中重复访问数据,同时稍微整体访问时间较慢,可能会在服务器负载下提供显着的应用程序性能。

就个人而言,我可能倾向于对每个请求都依赖 memcached,因为它更具可扩展性。

于 2012-07-18T18:31:14.280 回答
0

Kolink,我想对 Mike 提出另一种看法。首先,如果 getUser 请求的数量约为 50 个/页甚至几百个,那么存储问题就无关紧要了。

其次,memcached 的进程用完了,所以即使 memcached 在同一个系统上,每次get()调用仍然会遇到两次用户模式上下文切换,所以这里的关键问题是一个简单的统计问题:预期是什么每页的用户出现次数?例如,如果这是 2,那么您的本地 PHP 缓存将减少与 memcached 相关的上下文切换次数的一半。

然而,真正的节省将是通过使用 memcached 的multi-get功能——如果你用一组值调用memcache::get() ,PHP memcache 扩展会使用这个。但是,这需要两次算法和对代码的一些更改。安全地执行此操作的一种方法是根据您的第二个示例使用本地缓存的 getUser() 但添加页面结构的第 0 遍扫描以检测假定的 memcache 获取目标,进行唯一排序,然后使用基于此列表的多获取。

主线仍然可以使用缓存的 get 和故障返回到 D/B 以在 memcache 中设置 user-XXX,但是这样一来,高(比如 95%)的用户查询将满足单个进程外调用 memcached。

Yes, a bit of added complexity, but I think that the performance dividends make it well worthwhile trying.

于 2012-07-18T23:54:14.197 回答