Архив за месяц: Ноябрь 2013

getAllKeys в memcache

Не все расширения могут позволить работать с со всеми возможностями memcached, а некоторые функции работают неоптимально, например, getAllKeys выполняет запрос
stats cachedump N 0 200 раз (!). Я же предлагаю уйти от метода тотального перебора и спросить у сервера в каких точно slab он хранит данные. Для этого существует запрос stats items , привожу пример функции для кастомных запросов

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function getDataFromMemcached($command) {
  $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  if ($socket === FALSE)
    throw new Exception(socket_strerror(socket_last_error()));
  if (socket_connect($socket, memcached_host, memcached_port) === FALSE)
    throw new Exception(socket_strerror(socket_last_error()));
  if (socket_write($socket, "$command\n") === FALSE)
    throw new Exception(socket_strerror(socket_last_error()));
  $answer = "";
  while ($out = socket_read($socket, 1024, PHP_BINARY_READ)) {
    $answer .= $out;
    if (strlen($out) < 1024)
      break;
  }
  socket_close($socket);
  return $answer;
}
function getDataFromMemcached($command) {
  $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  if ($socket === FALSE)
    throw new Exception(socket_strerror(socket_last_error()));
  if (socket_connect($socket, memcached_host, memcached_port) === FALSE)
    throw new Exception(socket_strerror(socket_last_error()));
  if (socket_write($socket, "$command\n") === FALSE)
    throw new Exception(socket_strerror(socket_last_error()));
  $answer = "";
  while ($out = socket_read($socket, 1024, PHP_BINARY_READ)) {
    $answer .= $out;
    if (strlen($out) < 1024)
      break;
  }
  socket_close($socket);
  return $answer;
}

Вот допустим есть такая функция которая шлет запросы на сервер, теперь следует спросить у сервера Теперь следует спросить у сервера stats items, он скажет что-то вроде

................
STAT items:16:expired_unfetched 0
STAT items:16:evicted_unfetched 0
STAT items:17:number 4
STAT items:17:age 492
................

и становится понятно какие stab заняты. Затем извлечь идентификаторы slabs (это циферки 16,17…) и сделать запрос stats cachedump {$slab} 0 который вернет что нам нужно

ITEM b0d35f99c68e54c47a0839f5b4f91a73 [718 b; 1384951681 s]

потом остается только сделать get КЛЮЧ для получения значения. Пример выложен на гитхаб