2014-02-18 17 views
-1

所以我有以下代码:建议,以改进效率API调用和缓存

private function getArtistInfo($artist){ 
     $artisan = json_decode($artist, true); 
     $artistObj = array(); 
     //fb($artist); 
     $artistObj['id'] = $artisan['name']['ids']['nameId']; 

     $memcache = new Memcached($artistObj['id']); 
     $artistCache = $memcache->getMemcache(); 

     if($artistCache === false){ 

      $artistObj['name'] = $artisan['name']['name']; 
      $artistObj['image'] = $artisan['name']['images'][0]['url']; 

      $initArtist = array('id' => $artistObj['id'], 'name' => $artistObj['name'], 'image' => $artistObj['image']); 

      $artistObj = $this->buildArtist($artisan, $artistObj); 

       $memcache->setMemcache($artistObj);  

     } 
     else{ 
      $initArtist = array('id' => $artistCache['id'], 'name' => $artistCache['name'], 'image' => $artistCache['image']); 

     } 
      return $initArtist; 
    } 

现在代码的作品,但它需要getArtistInfo()太长,结束时我只想$ initArtist值;我希望我的客户端在创建好后立即让$ initArtist获得,并以某种方式让$ artistObj的缓存在后台运行。

到目前为止,我已经阅读了几个不同的主题,我认为这可能是有用的:事件委托,回调函数,call_user_func,观察者模式,线程,齿轮工等。但是,我不知道其中哪一个实际上会做什么我想要。请指点我正确的方向。

编辑:

我的Memcached类:

class Memcached { 

    private static $MEMCACHED_HOST = "localhost"; 
    private static $MEMCACHED_PORT = "11211"; 

    private $id, $key, $memcache, $cacheOK; 


    function __construct ($id){ 
     $this->id = $id; 
     $this->key = 'artistID_'. $this->id; 
     $this->memcache = new Memcache; 
     $this->cacheOK = $this->memcache->connect(Memcached::$MEMCACHED_HOST, Memcached::$MEMCACHED_PORT); 
    } 

    protected function getMemcache(){ 
     $artistInfo = null; 

     if($this->cacheOK === true){ 
      $artistInfo = $this->memcache->get($this->key); 
     } 

     if($artistInfo === false){ 
      return false; 
     } 

     return $artistInfo; 

    } 


    public function setMemcache($artistInfo){ 

     $this->memcache->set($this->key, $artistInfo, 0, 60); 

    } 

} 

我buildArtist()代码:

private function buildArtist($artisan, $artistObj){ 

     $artistObj['amgID'] = $artisan['name']['ids']['amgPopId']; 


     $discography = $artisan['name']['discography']; 

     foreach($discography as $album){ 
      $albumID = $album['ids']['amgPopId']; 
      preg_match('/(\d+)/', $albumID, $matches); 
      $albumObj['amgAlbumID'] = $matches[1]; 
      $albumObj['title'] = $album['title']; 
      $albumObj['releaseDate'] = $album['year']; 

      $albumObj['more'] = $this->getMoreMusic($albumObj['title'], $artistObj['name']); 


      $artistObj['discography'][] = $albumObj; 
     } 
     return $artistObj; 
    } 

回答

0

嗯,这是不完全清楚过长有多长,或者这段代码的一部分是减慢你的速度。就我们所知,缓慢的部分不是将数据存储在Memcached中的部分。

在任何情况下,一旦你确定这是你的瓶颈,有一两件事可以做,以实现这种类型的乱序执行的是使用像ZeroMQ一个brokerless消息队列接受,需要缓存的JSON对象。然后,一个单独的PHP脚本可以承担在任何Web请求之外异步处理和缓存这些请求的工作。这个单独的脚本可以通过一个cron-job或者一些其他的并行处理缓存部分的工作管理器来运行。

0

你想要使用setget而不是使用memcache持久性ID,我什至不知道什么setMemcachegetMemcache是,但他们不在扩展文档中。

下面是从文档的例子:

<?php 
$m = new Memcached(); 
$m->addServer('localhost', 11211); 

if (!($ip = $m->get('ip_block'))) { 
    if ($m->getResultCode() == Memcached::RES_NOTFOUND) { 
     $ip = array(); 
     $m->set('ip_block', $ip); 
    } else { 
     /* log error */ 
     /* ...  */ 
    } 
} 

请出示的buildArtist代码为帮助优化它。

+0

感谢您的帮助马丁。 请参阅我的编辑。 目前它需要getArtistInfo()差不多15秒来完成执行:( – kyw

+0

@twiart我们需要看到getMoreMusic接下来;)......它看起来像在你的循环中运行该查询导致了问题。如果您可以使用'JOIN'来获取一个查询中的所有音乐,这可能会解决您的问题 – Martin

+0

感谢您的回复。 getMoreMusic()确实是瓶颈;它是另一个调用带有更多循环的API的函数。通过JOIN,你的意思是implode()函数有点加入?有没有办法像批处理一样运行API?也许我想知道的是,一次完成多个API调用时的最佳做法是什么......? – kyw