Php 如何使用memcached提高社交网站的性能?

Php 如何使用memcached提高社交网站的性能?,php,memcached,Php,Memcached,我想在我的社交网站上实现memcached。作为一个社交网络,大多数数据变化非常频繁 例如,如果我要在缓存中存储一个用户的10000个朋友,那么每当他添加一个朋友时,缓存都需要更新。这很简单,但也需要在其他人将其添加为好友时进行更新。仅仅在朋友名单上就有很多更新 还有一些用户博客和公告,它们不停地发布新的博客和公告,你只能在朋友列表中看到用户创建的博客和公告,所以我认为这很难缓存 我可能会看到缓存一些只有在用户更新他们的配置文件时才会更改的配置文件信息,但这将为每个用户创建一个缓存记录,如果有1

我想在我的社交网站上实现memcached。作为一个社交网络,大多数数据变化非常频繁

例如,如果我要在缓存中存储一个用户的10000个朋友,那么每当他添加一个朋友时,缓存都需要更新。这很简单,但也需要在其他人将其添加为好友时进行更新。仅仅在朋友名单上就有很多更新

还有一些用户博客和公告,它们不停地发布新的博客和公告,你只能在朋友列表中看到用户创建的博客和公告,所以我认为这很难缓存


我可能会看到缓存一些只有在用户更新他们的配置文件时才会更改的配置文件信息,但这将为每个用户创建一个缓存记录,如果有100000多个用户,这将是大量的缓存。这是个好主意吗?

我想说,在可能的地方缓存是个好主意。。。。大多数情况下,您将能够比传统的RDBMS更快地从memcached中提取项目(特别是如果您有复杂的连接等)。我目前成功地采用了这样一种策略,以下是我从经验中学到的:

  • 如果可能,无限期缓存,并在进行更改时写入新值。尽量不要执行显式删除,因为您可能会导致竞态条件,对试图更新缓存的数据进行多个并发访问。如果缓存中不存在项,也要实现锁定,以防止上述问题(在循环中使用memcached“add”+短睡眠时间)

  • 如果可能,使用队列在后台刷新缓存。我的实现目前使用在后台+beanstalkd中运行的多线程perl进程,从而防止前端出现延迟。大多数时间更改可能会产生短暂的延迟

  • 如果可能的话,使用memcached getmulti,许多单独的memcached调用实际上会累加起来


  • 分层缓存,在检查项时,首先检查本地数组,然后是memcached,然后是db。在首次访问后缓存本地数组,以防止在同一项目的脚本执行中多次命中memcached。编辑:为了澄清这一点,如果使用PHP等脚本语言,则本地数组的有效期仅与当前脚本执行时间相同:)例如:

    class Itemcache {
        private $cached_items = array();
        private $memcachedobj;
    
        public function getitem($memcache_key){
            if(isset($this->cached_items[$memcache_key])){
                return $this->cached_items[$memcache_key];
            }elseif($result = $this->memcachedobj->get($memcache_key)){
                $this->cached_items[$memcache_key] = $result;
                return $result;
            }else{
                // db query here as $dbresult
                $this->memcachedobj->set($memcache_key,$dbresult,0);
                $this->cached_items[$memcache_key] = $dbresult;
                return $dbresult;
        }
    }
    
  • 编写一个包装器函数来实现上述缓存策略#4

  • 在memcached中使用一致的密钥结构,例如“userinfo_{user.pk}”,其中user.pk是rdbms中用户的主键

  • 如果您的数据需要后处理,请在可能的情况下在放入缓存之前进行此处理,这样可以在每次命中该数据时节省几个周期


  • 这个问题真的需要一个更好的标题。“首次访问后缓存本地数组,以防止在同一项目的脚本执行中多次命中memcached。”这是什么意思?您的意思是将数组保存为会话还是其他形式?我还想知道如何缓存朋友列表以供使用,我看到的问题是用户经常更新和添加朋友,另外,如果用户将此人添加为朋友,则每次添加朋友时都需要更新缓存,这是非常常见的,另外,如果有50000个用户,则可以缓存50000个用户的好友列表。下一个命令->一些列表可能有20000个好友ID?通过数组,我是指本地。php示例。在第一次从memcached获取结果后,您有一个名为$array\u cache的类var,使用$this->array\u cache[$memcache\u key]=$memcache\u值将结果保存在数组中;然后在下一个方法调用中,如果(isset($this->array\u cache[$memcache\u key])返回$this->array\u cache[$memcache\u key];这样,在当前脚本执行期间,它就不需要为相同的结果再次调用memcached(如果您最终为相同的项调用了两次或更多次)。脚本的下一次调用当然会再次调用memcached。->接下来,就50k用户而言,您可能希望对db查询进行基准测试,而不是将其全部存储在memcached中,因为生成的数组可能相当大(并且可能会对网络造成很大的拖累)。我认为网络传输时间比在数组中查找项目更重要,因为您可以将数组键设置为用户id,如果使用php,则使用array_key_exists/isset。->接下来,我为用户建立好友关系所使用的方法是在后台同时刷新我和我朋友的好友列表,每个列表都对好友进行db查询并存储在缓存中。。。。我们网络上的好友列表比5万个用户小一点,它能很好地满足我们的需要。。。。就像我上面说的,基准测试。顺便说一句,我真的很讨厌这里的评论格式:(