考虑以下代码:
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);
}发布于 2012-07-19 02:31:14
最终,memcached是在内存存储中,就像在PHP数组中存储值一样。如果memcached实例在运行代码的同一台服务器上,那么我肯定会说只使用memcached,而不是同时使用memcached和PHP数组,因为通过将相同的数据存储在内存中两次,最终会占用机器上大约两倍的内存。
如果memcached位于独立的基础设施上(这很可能),那么我想我会考虑为用户存储的数据的大小。如果它很大,并且您可能在PHP数组中存储了大量用户,这意味着您可能会在web服务器上消耗比您所希望的更多的内存,在这种情况下,重复访问memcached中的数据,虽然总体访问时间略慢,但在服务器负载下可能会提供显著的应用程序性能。
就我个人而言,我可能倾向于为每个请求依赖memcached,因为它更具可伸缩性。
发布于 2012-07-19 07:54:14
科林克,我想用另一种观点看待迈克。首先,如果getUser请求的数量大约为50个/页,甚至几百个,那么存储问题就不重要了。
其次,memcached在进程外运行,所以即使memcached在同一系统上,每次get()调用都会遇到两次用户模式上下文切换,所以这里的关键问题是一个简单的统计问题:预计每个页面的用户出现次数是多少?如果是2,那么您的本地PHP缓存将是memcached相关上下文切换数量的一半。
但是,真正的节省是通过使用memcached的multi-get功能来实现的--如果使用一组值调用memcache::get(),PHP memcache扩展就会使用这个功能。但是,这需要两遍算法和对代码的一些更改。要安全地做到这一点,一种方法是按照第二个示例使用本地缓存的getUser(),但是添加页面结构的第0次扫描来检测假定的memcache get目标,执行唯一排序,然后基于此列表使用多个get来填充本地缓存。
主线仍然可以使用缓存的get和故障返回到D/B来在memcache中设置user-XXX,但是通过这种方式,对memcached的单个进程外调用就可以满足很高的用户查询(比如95%)。
是的,增加了一点复杂性,但我认为性能红利使它值得一试。
https://stackoverflow.com/questions/11547737
复制相似问题