Получить размер ключевого значения redis в памяти

Я пытаюсь получить размер ключ-значение или просто ключ или просто значение в Redis.

Использование команды debug object key возвращает сериализованный размер ключ-значение, если оно должно быть записано на диск, а не фактическое количество байтов, которое оно использует в памяти.

Это можно подтвердить, проверив исходный код (на основе этого Redis: Показать размер базы данных /размер для ключей)

https://github.com/antirez/redis/blob/4082c38a60eedd524c78ef48c1b241105f4ddc50/src/debug.c#L337-L343

https://github.com/antirez/redis/blob/4082c38a60eedd524c78ef48c1b241105f4ddc50/src/rdb.c#L663-L671

глядя на исходный код:

/* Save a string object as [len][data] on disk. If the object is a string
 * representation of an integer value we try to save it in a special form */
ssize_t rdbSaveRawString(rio *rdb, unsigned char *s, size_t len) {
  int enclen;
  ssize_t n, nwritten = 0;

  /* Try integer encoding */
  if (len <= 11) {
    unsigned char buf[5];
    if ((enclen = rdbTryIntegerEncoding((char*)s,len,buf)) > 0) {
      if (rdbWriteRaw(rdb,buf,enclen) == -1) return -1;
      return enclen;
    }
  }

  /* Try LZF compression - under 20 bytes it's unable to compress even
   * aaaaaaaaaaaaaaaaaa so skip it */
  if (server.rdb_compression && len > 20) {
    n = rdbSaveLzfStringObject(rdb,s,len);
    if (n == -1) return -1;
    if (n > 0) return n;
    /* Return value of 0 means data can't be compressed, save the old way */
  }

  /* Store verbatim */
  if ((n = rdbSaveLen(rdb,len)) == -1) return -1;
  nwritten += n;
  if (len > 0) {
    if (rdbWriteRaw(rdb,s,len) == -1) return -1;
    nwritten += len;
  }
  return nwritten;
}

И подтвердите через redis-cli:

127.0.0.1:6379> set a aaaaaaaaaaaaaaaaaaa
OK
127.0.0.1:6379> debug object a
Value at:0x7f985822f168 refcount:1 encoding:embstr serializedlength:20 lru:11611136 lru_seconds_idle:2
127.0.0.1:6379> set a aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
OK
127.0.0.1:6379> debug object a
Value at:0x7f985827c428 refcount:1 encoding:embstr serializedlength:12 lru:11611147 lru_seconds_idle:1

Все различные инструменты CLI сообщают о сериализованном размере объекта, а не о размере памяти, который является интересным и важным.


person Avner Barr    schedule 20.03.2018    source источник


Ответы (1)


Начиная с Redis v4, команда MEMORY USAGE намного лучше угадывает размер ключа. и его значение.

person Itamar Haber    schedule 20.03.2018
comment
Кажется, он не принимает во внимание ключ. Например: 127.0.0.1:6379> установить aa OK 127.0.0.1:6379> использование ПАМЯТИ a (целое число) 52 127.0.0.1:6379> установить b случайная длинная строка с большим количеством букв OK 127.0.0.1:6379> использование ПАМЯТИ b (целое число) 83 127.0. 0.1:6379› set randomlongstringwithlotsofletters b OK 127.0.0.1:6379› MEMORY use randomlongstringwithlotsofletters (integer) 52 127.0.0.1:6379› - person Avner Barr; 21.03.2018
comment
Какую версию вы используете? - person Itamar Haber; 22.03.2018
comment
127.0.0.1:6379›информация # Сервер redis_version:4.0.1 - person Avner Barr; 22.03.2018
comment
Обновите до более новой версии - я лично представил исправление проблемы, которую вы описываете :) - person Itamar Haber; 23.03.2018