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

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

Какой самый простой способ получить дамп всех пар ключ/значение в плоский файл? Сначала я посмотрел на java net.spy.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: Вышеупомянутый script, похоже, не возвращает все сопоставления. Если я вставляю строку count($entries), она возвращает только немного более 50 тыс., Даже если параметр предела установлен в 100 М, но выполнение stats items из telnet показывает более 5 М записей. Кто-нибудь знает, почему это может быть так?

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

Ответ 1

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

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

Из статьи:

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

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

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

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

Ответ 2

memccat

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

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

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

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

memcdump

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

memcdump --servers=localhost | tee my_keys.lst

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

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

Чтобы memcdump все объекты на экран через memcdump/memdump и netcat:

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

Memcached-инструмент

В последней версии memcached есть также команда memcached-tool, например

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

Ответ 3

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

Ответ 4

Я использовал этот bash script

#!/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/порт при необходимости

Ответ 5

удар

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

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

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