web-dev-qa-db-fra.com

Quel est le moyen le plus simple d’obtenir une sauvegarde de toutes les clés memcached dans un fichier?

Cela provient d'un seul serveur memcached avec environ 20 millions de clés (sans date d'expiration) et environ 2 G de données.

Quel est le moyen le plus simple d’effectuer une sauvegarde de toutes les paires clé/valeur dans un fichier à plat? J'ai d'abord regardé le net.spy.memcached.MemcachedClient Java, mais ce client ne prend pas en charge l'obtention de toutes les clés (je pense). Si j'avais une liste de toutes les clés (ce que je n'ai pas), je pourrais facilement utiliser ce client pour obtenir toutes les valeurs.

Je sais que je peux obtenir toutes les clés à l'aide de certaines commandes telnet (par exemple, telnet localhost 11211; éléments statistiques; stats cachedump), mais je ne vois pas comment automatiser cela de manière robuste.

EDIT: Voici ce que j'ai fait pour que cela fonctionne sur un serveur memcached jouet sur ma machine. Cela semble fonctionner, mais je ne mets que deux clés dans memcached. J'espère donc que cette méthode évoluera:

Commandes Shell:

Sudo yum install memcached
Sudo /etc/init.d/memcached restart # maybe unnecessary
Sudo yum install php
Sudo yum install php-pecl-memcache
Sudo service httpd reload

script php, basé sur this :

<?php
$memcache = new Memcache();
$memcache->connect('127.0.0.1', 11211) or die ("Could not connect");
$list = array();
$allSlabs = $memcache->getExtendedStats('slabs');
$items = $memcache->getExtendedStats('items');
foreach($allSlabs as $server => $slabs) {
    foreach($slabs AS $slabId => $slabMeta) {
        if (!is_int($slabId)) {
            continue;
        }
        $cdump = $memcache->getExtendedStats('cachedump', (int) $slabId, 100000000);
        foreach($cdump AS $server => $entries) {
            if ($entries) {
                foreach($entries AS $eName => $eData) {
                    print_r($eName);
                    print_r(":");
                    $val = $memcache->get($eName);
                    print_r($val);
                    print_r("\n");
                }
            }
        }
    }
}
?>

EDIT2: Le script ci-dessus ne semble pas renvoyer tous les mappages. Si j'insère la ligne count($entries), elle ne renvoie qu'un peu plus de 50 000, même si le paramètre limit est défini sur 100M, mais l'exécution de stats items à partir de telnet affiche plus de 5 millions d'entrées. Est-ce que quelqu'un sait pourquoi cela pourrait être le cas?

EDIT3: Ce link suggère que cachedump n’obtient pas toutes les clés de memcached. J'ai atteint une limite d'environ 50 000 clés renvoyées par cachedump, ce script PHP ou un script Perl similaire à celui du lien fourni par Zach Bonham. Y a-t-il un moyen de contourner cela?

10
jonderry

disclaimer: Je ne sais pas ce que je fais, cela me semblait être un problème intéressant.

Avez-vous vu cet article? "Comment vider les clés de Memcache" par Lars Windolf. 

De l'article:

Memcache lui-même fournit les moyens d’accumuler les données. Le protocole Fournit des commandes permettant d'intégrer les données organisées en dalles (Catégories de données d'une plage de tailles donnée. Il existe toutefois des limitations importantes :

  • Vous ne pouvez sauvegarder des clés que par classe de dalle (clés ayant à peu près la même taille de contenu)
  • Vous ne pouvez vider qu'une page par classe de dalle (1 Mo de données)
  • Ceci est une fonctionnalité non officielle qui peut être supprimée à tout moment.

Effectivement, cela nécessite une certaine connaissance de la façon dont memcache stocke les données en mémoire (ce que je ne fais pas). Vous devez trouver chaque "dalle", vous pouvez ensuite vider les clés de cette dalle, puis les valeurs de ces clés.

Il existe une section d'outils dans l'article qui utilise différentes langues pour vider au moins les clés, mais seul le script Perl dumpe les clés et les valeurs. 

12
Zach Bonham

memccat

Voici le script que j'utilise pour vider tous les objets dans les fichiers correspondants:

while read -r key; do
    [ -f "$key" ] || echo "get $key" | nc localhost 11211 > "$key.dump";
done < <(memcdump --server localhost)

Il utilise la commande memcdump qui devrait faire partie des utilitaires memcached.

Pour les objets compressés, voir: Comment vider un objet compressé pour une clé donnée à partir de Memcache?

memcdump

Pour extraire une liste de clés d’un serveur, utilisez l’outil memcdump/memdump, par exemple.

memcdump --servers=localhost | tee my_keys.lst

Pour imprimer la valeur d'un élément, utilisez netcat:

echo "get 13456_-cache-some_object" | nc localhost 11211

Pour vider tous les objets dans l’écran via memcdump/memdump et netcat:

memcdump --servers=localhost | xargs -L1 -I% sh -c 'echo "get %" | nc localhost 11211'

memcached-tool

Dans la version récente de memcached, il existe égalementmemcached-toolcommand, par exemple.

memcached-tool localhost:11211 dump | less # dumps keys and values
4
kenorb

Il existe une limite codée en dur de 2 Mo pour le vidage d'une dalle. À moins que vous ne réécriviez le fichier do_item_cachedump, vous ne pourrez pas extraire toutes les clés.

3
user1871696

J'ai utilisé ce script bash

#!/bin/sh
MESSAGE=`memdump --servers="127.0.0.1"`
while read -r line; do
    echo $line
    VALUE=`echo "get $line" | nc 127.0.0.1 11211`
    echo $VALUE
done <<< "$MESSAGE"

il suffit de remplacer IP/port si nécessaire

2
greenone83

Bash

Utiliser Bash et sauvegarder dans le fichier:

exec {memcache}<>/dev/tcp/localhost/11211
printf "stats items\nquit\n" >&${memcache}
cat <&${memcache} > myfile.txt

Connexes: Ecriture d'un client Redis en pure bash (c'est Redis, mais approche très similaire)

0
kenorb