2012-05-29 39 views

cevap

36

Memcached bu işlevi kutudan çıkarmaz, böylece bunu kendiniz oluşturmanız gerekir.

Bunu çözme biçimim, anahtar grupları için uygulamamda bir önek (veya ad alanı) tanımlamaktır. Memcached'de belirttiğim herhangi bir anahtarın önündeki bu önek vardır. Memcached'den "silmek" istediğim zaman, öneki değiştiriyorum. Ve ne zaman Memcached'de bir anahtar aramak istediğimde, bu öneki ekliyorum.

Sizin durumunuzda, önek ayarını MyAppPrefix1 olarak ayarlayarak başlayabilirsiniz, böylece anahtarlarınız MyAppPrefix1::app_333333, MyAppPrefix1::app_444444 olarak kaydedilecektir.

Daha sonra bu girdileri "silmek" istediğinizde, uygulamanızı MyAppPrefix2 kullanacak şekilde ayarlayın. Daha sonra, Memcached'den bir anahtar almayı denediğinizde app_333333, MyAppPrefix2::app_333333'u arar ve ilk defa, sanki silinmiş gibi bulamaz.

+1

Ve nasıl silerim eski girdiler? süre doldurarak? –

+0

@ AlfonsoFernandez-Ocampo evet, neden olmasın? Memcache gerektiğinde mükemmel görünüyor – yefrem

+0

onları silecektir, ancak, Memcached sona erme süresinden sonra veya dolmak üzere olduğunda silinecek? – kscius

4

Nasıl php bu işlevi hakkında:

function deletekeysbyindex($prefix) { 
    $m = new Memcached(); 
    $m->addServer('localhost', 11211); 
    $keys = $m->getAllKeys(); 
    foreach ($keys as $index => $key) { 
     if (strpos($key,$prefix) !== 0) { 
      unset($keys[$index]); 
     } else { 
      $m->delete($key); 
     } 
    } 
    return $keys; 
} 

$ öneki ile başlayan anahtarları siler ve kaldırılan tüm anahtarların bir listesini döndürür. Bunu şimdi paylaşılan bir sunucuda 30.000'den fazla tuşla çalıştırdım ve oldukça hızlıydı - muhtemelen bir saniyeden az.

+2

Çalışması garanti edilmez. http://php.net/manual/en/memcached.getallkeys.php "Tüm tuşlara geri dönmeyi garanti etmediğinden, tüm anahtarların geri döndüğünü de kabul edemezsiniz." –

+2

Bunu işaretlediğiniz için teşekkürler @TimMartens. Sanırım alabildiğin kadar iyi mi? Keşke 'getAllKeys()' yönteminin ne zaman ve neden kısa sürdüğü ile ilgili biraz daha fazla bilgi olsaydı .. bu konuda herhangi bir ışık tutabilir misin? Dokümanlar oldukça yararsızdır. – billynoah

0

Bunu yalnızca memcache'de yapamayız. Böyle bu işlevi

public function clearByPrefix($prefixes = array()) { 
    $prefixes = array_unique($prefixes); 

    $slabs = $this->memcache->getExtendedStats('slabs'); 
    foreach ($slabs as $serverSlabs) { 
     if ($serverSlabs) { 
      foreach ($serverSlabs as $slabId => $slabMeta) { 
       if (is_int($slabId)) { 
        try { 
         $cacheDump = $this->memcache->getExtendedStats('cachedump', (int) $slabId, 1000); 
        } catch (Exception $e) { 
         continue; 
        } 

        if (is_array($cacheDump)) { 
         foreach ($cacheDump as $dump) { 
          if (is_array($dump)) { 
           foreach ($dump as $key => $value) { 

            $clearFlag = false; 
            // Check key has prefix or not 
            foreach ($prefixes as $prefix) { 
             $clearFlag = $clearFlag || preg_match('/^' . preg_quote($prefix, '/') . '/', $key); 
            } 
            // Clear cache 
            if ($clearFlag) { 
             $this->clear($key); 
            } 
           } 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
} 

Ve diyoruz: Biz sadece bunu yapabilirsiniz

 $prefixes = array(); 

     array_push($prefixes, 'prefix1_'); 
     array_push($prefixes, 'prefix2_'); 
     array_push($prefixes, 'prefix3_'); 

     $this->clearByPrefix($prefixes); 
+0

Kodunuzun anlaşılması kolay olsa bile, ne yaptığını ve neden bu çözümün kurmaya yardımcı olduğuna inandığınızı açıklayabilirsiniz. Bu arada, sadece strpos'u arayabileceğiniz zaman preg_match gerçekten çok fazla. –

+0

Belki de koduma daha fazla yorum eklemeliyim :) Preg_match hakkında, bunun bir overkill olduğunu düşünmüyorum. Biliyorsun, bu dava için basit bir şey. İlacın gelecekte daha karmaşık olacağını bile düşünüyorum. :) Yorumun için teşekkürler kardeşim! –

0

Bu yavaş biraz da olsa çalışır kesmek. 0.6 milyon tuşa sahip bir sunucuda, tamamlanması yarım saniye sürdü.

$prefix = 'MyApp::Test'; 
    $len = strlen($prefix); 

    $proc = popen('/usr/local/bin/memdump --servers=localhost', 'r'); 
    while (($key = fgets($proc)) !== false) { 
     if (substr_compare($key, $prefix, 0, $len) === 0) { 
      $memcached->delete(substr($key, 0, -1)); 
     } 
    }