web-dev-qa-db-fra.com

Comment supprimer des éléments avec la même clé de préfixe dans memcached?

Par exemple, j'ai des éléments en cache avec le même préfixe, tels que

'app_111111', 'app_222222', 'app_333333', ...

Puis-je supprimer ces éléments 'app_xxxxxx' à l'aide de commandes memcached?

24
northtree

Memcached n'offre pas cette fonctionnalité par défaut, vous devez donc la construire vous-même.

Pour résoudre ce problème, vous devez définir un préfixe (ou un espace de nom) dans mon application pour les groupes de clés. Toute clé que je mets dans memcached a ce préfixe avant elle. Chaque fois que je veux "supprimer" des trucs de Memcached, je change juste le préfixe. Et chaque fois que je veux rechercher une clé dans Memcached, j'y ajoute ce préfixe.

Dans votre cas, vous pouvez commencer par définir le préfixe sur, par exemple, MyAppPrefix1, afin que vos clés soient stockées sous la forme MyAppPrefix1::app_333333, MyAppPrefix1::app_444444.

Plus tard, lorsque vous souhaitez "supprimer" ces entrées, configurez votre application pour utiliser MyAppPrefix2. Ensuite, lorsque vous essayez d’obtenir une clé de Memcached appelée app_333333, elle recherchera MyAppPrefix2::app_333333 et ne la trouvera pas la première fois, comme si elle avait été supprimée.

38
ziad-saab

Que diriez-vous de cette fonction en 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;
}

Supprime les clés commençant par $ préfixe et retourne une liste de toutes les clés supprimées. Je l'ai utilisé sur plus de 30 000 clés tout à l'heure sur un serveur partagé et ce fut assez rapide - probablement moins d'une seconde.

4
billynoah

Nous ne pouvons pas le faire en une seule requête à memcache. Nous pouvons juste faire ceci:

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

Et appelez cette fonction comme ceci:

        $prefixes = array();

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

        $this->clearByPrefix($prefixes);
0
Last person

C'est un hack qui fonctionne, bien qu'un peu lent. Sur un serveur avec 0,6 million de clés, l’opération a pris une demi-seconde.

    $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));
        }
    }
0
Joyce Babu