Каков самый простой способ получить дамп всех ключей memcached в файл?

это всего лишь один сервер memcached с ключами 20M (без истечения срока действия) и около 2G данных.

какой самый простой способ получить дамп всех пар ключ/значение в плоский файл? Сначала я посмотрел на java net.шпион.из memcached.MemcachedClient, но этот клиент не поддерживает получение всех ключей (я думаю). Если бы у меня был список всех ключей (которых у меня нет), я мог бы легко использовать этот клиент для получения всех значений.

Я знаю, что могу получить все ключи, используя некоторые telnet команды (например, telnet localhost 11211; Stats items; stats cachedump), но мне не ясно, как автоматизировать это надежно.

EDIT: вот что я сделал, чтобы заставить это работать на игрушечном сервере memcached на моей машине. Кажется, это работает, но я поместил только два ключа в memcached, поэтому, надеюсь, этот метод будет масштабироваться нормально:

консоли команды:

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

PHP-скрипт, на основе этой:

<?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: приведенный выше скрипт, похоже, не верните все сопоставления. Если вставить строку count($entries), он возвращает только чуть более 50k, даже с параметром limit, установленным в 100M, но выполняющим stats items из telnet показывает более 5M записей. Кто-нибудь знает почему это может быть дело?

EDIT3: это ссылке предполагает, что cachedump не получает все ключи от memcached. Я ударил предел около 50k ключей, которые возвращаются либо cachedump, этот PHP-скрипт, либо Perl-скрипт, подобный тому, который указан в ссылке Зак Бонэм. Есть ли способ обойти это?

4 ответов


отказ от ответственности: я не знаю, что я делаю, просто звучало как интересная проблема.

вы видели эту статью? "как сбросить ключи из Memcache" Ларс Windolf.

из статьи:

Memcache сам по себе предоставляет средства для пика в данные. Протокол предоставляет команды для пикирования в данные, организованные слябами (категории данных заданного диапазона размеров. Есть некоторые значительные хотя ограничения:

  • вы можете только сбрасывать ключи на класс плиты (ключи с примерно одинаковым размером содержимого)
  • вы можете сбросить только одну страницу на класс плиты (1 МБ данных)
  • это неофициальная функция, которая может быть удалена в любое время.

эффективно, это требует некоторых знаний о том, как memcache хранит данные в памяти (чего я не делаю). Вам нужно найти каждую "плиту", тогда вы можете сбросить ключи для этой плиты, и затем, в конечном счете, значения для этих ключей.

в статье есть раздел инструментов, который использует различные языки для сброса по крайней мере ключей, но только скрипт perl сбрасывает ключи и значения.


memccat

вот скрипт, который я использую для сброса всех объектов в соответствующие файлы:

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

он использует memcdump команда, которая должна быть частью memcached utils.

для сжатых объектов, см.: как сбросить сжатый объект для данного ключа из Memcache?

memcdump

сбросить список ключей с сервера, используйте memcdump/, например,

memcdump --servers=localhost | tee my_keys.lst

To вывести значение одного элемента, используйте netcat:

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

сбросить все объекты на экране с помощью memcdump/memdump и netcat:

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

Баш

использование Bash и сохранение в файл:

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

по теме: написание клиента Redis в pure bash (это Redis, но очень похожий подход)

memcached-tool

в последней версии memcached появилась memcached-tool команды, например,

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

существует жестко закодированный предел 2 МБ для сброса плиты. Если вы не перепишете do_item_cachedump, вы не сможете получить все ключи.


я использовал этот скрипт 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"

просто замените IP / port при необходимости