2012-05-29 4 views

Antwort

36

Memcached bietet diese Funktionalität nicht sofort, so dass Sie es selbst erstellen müssen.

Die Lösung dieses Problems besteht darin, in meiner Anwendung ein Präfix (oder einen Namespace) für Schlüsselgruppen zu definieren. Jeder Schlüssel, den ich in memcached gesetzt habe, hat dieses Präfix davor. Wann immer ich Sachen von Memcached "löschen" möchte, ändere ich einfach das Präfix. Und wann immer ich einen Schlüssel in Memcached suchen möchte, füge ich dieses Präfix hinzu.

In Ihrem Fall könnten Sie beginnen, indem Sie das Präfix beispielsweise auf MyAppPrefix1 setzen, sodass Ihre Schlüssel als MyAppPrefix1::app_333333, MyAppPrefix1::app_444444 gespeichert werden.

Später, wenn Sie diese Einträge "löschen" möchten, stellen Sie Ihre Anwendung auf MyAppPrefix2. Wenn Sie dann versuchen, einen Schlüssel aus Memcached mit der Bezeichnung app_333333 zu erhalten, sucht er nach MyAppPrefix2::app_333333 und findet ihn nicht beim ersten Mal, als wäre er gelöscht worden.

+1

Und wie löschen Sie alte Einträge? nach Ablauf der Zeit? –

+0

@ AlfonsoFernandez-Ocampo ja, warum nicht? Memcache löscht sie bei Bedarf – yefrem

+0

das sieht gut aus, aber Memcached löscht nach der Ablaufzeit oder wenn es kurz davor ist, voll zu sein? – kscius

4

Wie über diese Funktion in php:

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; 
} 

Löscht Schlüssel mit $ Präfix beginnen und gibt eine Liste aller entfernt Tasten. Ich habe das jetzt auf mehr als 30.000 Tasten auf einem gemeinsam genutzten Server ausgeführt und es war ziemlich schnell - wahrscheinlich weniger als eine Sekunde.

+2

Dies funktioniert nicht garantiert. http://php.net/manual/en/memcached.getallkeys.php "Da memcache nicht garantiert, alle Schlüssel zurückzugeben, können Sie auch nicht davon ausgehen, dass alle Schlüssel zurückgegeben worden sind." –

+2

Danke für das Hinzeigen @TimMartens. Ich nehme an, es ist ungefähr so ​​gut, wie du es bekommen kannst. Ich wünschte, es gäbe ein bisschen mehr Informationen darüber, wann und warum die 'getAllKeys()' Methode wahrscheinlich zu kurz kommen wird. Kannst du etwas dazu sagen? Die Dokumente sind ziemlich wenig hilfreich. – billynoah

0

Wir können das nicht in nur einer Anforderung Memcache tun. Wir können nur das tun:

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); 
            } 
           } 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
} 

Und rufen Sie diese Funktion wie folgt aus:

 $prefixes = array(); 

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

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

Auch wenn Ihr Code einfach zu verstehen scheint, könnten Sie erklären, was er tut und warum Sie glauben, dass diese Lösung dem Fragesteller hilft. Übrigens, preg_match, wenn man nur strpos aufrufen kann, ist wirklich ein Overkill. –

+0

Vielleicht sollte ich weitere Kommentare in meinem Code hinzufügen :) Über preg_match, glaube ich nicht, dass es ein Overkill ist. Du weißt, es ist nur eine einfache Sache für diesen Fall. Ich habe sogar vor, dass die Regex in Zukunft noch komplexer sein wird. :) Danke für deinen Kommentar, Bruder! –

0

Dies ist ein Hack, der langsam, wenn auch etwas funktioniert. Auf einem Server mit 0,6 Millionen Schlüsseln dauerte es eine halbe Sekunde.

$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)); 
     } 
    } 
Verwandte Themen