2014-02-18 48 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