当我将一些对象写入redis时,我可以获得不同的内存使用情况统计信息。我想知道这是怎么发生的。
简单示例:
127.0.0.1:6379> set a 1
OK
127.0.0.1:6379> MEMORY usage a
(integer) 49
127.0.0.1:6379> set a "1"
OK
127.0.0.1:6379> MEMORY usage a
(integer) 49
127.0.0.1:6379> set a \x01 <<<< Message packed of number 1
OK
127.0.0.1:6379> MEMORY usage a
(integer) 55
127.0.0.1:6379> set a '\x01' <<<< Message pack of number 1 but added ''
OK
127.0.0.1:6379> MEMORY usage a
(integer) 55
127.0.0.1:6379> set a "\x01" <<<<< Message pack of number 1 but added ""
OK
127.0.0.1:6379> MEMORY usage a
(integer) 52
每次和编码(作为embstr):
127.0.0.1:6379> set a 1
OK
127.0.0.1:6379> DEBUG OBJECT a
Value at:0x7f9858217ba0 refcount:2147483647 encoding:int serializedlength:2 lru:11691925 lru_seconds_idle:222
127.0.0.1:6379> set a "1"
OK
127.0.0.1:6379> DEBUG OBJECT a
Value at:0x7f9858217ba0 refcount:2147483647 encoding:int serializedlength:2 lru:11692152 lru_seconds_idle:1
127.0.0.1:6379> set a \x01
OK
127.0.0.1:6379> DEBUG OBJECT a
Value at:0x7f98563a1398 refcount:1 encoding:embstr serializedlength:5 lru:11692162 lru_seconds_idle:0
127.0.0.1:6379> set a '\x01'
OK
127.0.0.1:6379> DEBUG OBJECT a
Value at:0x7f98563a13e0 refcount:1 encoding:embstr serializedlength:5 lru:11692168 lru_seconds_idle:1
127.0.0.1:6379> set a "\x01"
OK
127.0.0.1:6379> DEBUG OBJECT a
Value at:0x7f98563a1788 refcount:1 encoding:embstr serializedlength:2 lru:11692177 lru_seconds_idle:1
更复杂的值(带数字的字符串)
127.0.0.1:6379> set a "abc123"
OK
127.0.0.1:6379> DEBUG OBJECT a
Value at:0x7f985821b260 refcount:1 encoding:embstr serializedlength:7 lru:11692243 lru_seconds_idle:3
127.0.0.1:6379> MEMORY usage a
(integer) 57
127.0.0.1:6379> set a \xa6abc123
OK
127.0.0.1:6379> MEMORY usage a
(integer) 61
127.0.0.1:6379> DEBUG OBJECT a
Value at:0x7f985821b320 refcount:1 encoding:embstr serializedlength:11 lru:11692273 lru_seconds_idle:9
127.0.0.1:6379> set a "\xa6abc123"
OK
127.0.0.1:6379> MEMORY usage a
(integer) 58
127.0.0.1:6379> DEBUG OBJECT a
Value at:0x7f985821b260 refcount:1 encoding:embstr serializedlength:8 lru:11692291 lru_seconds_idle:11
127.0.0.1:6379>
一个大的JSON字符串(然后是消息打包),编码是&#34; raw&#34;
127.0.0.1:6379> set a '[{"id":1,"first_name":"Kyrstin","last_name":"Ifill","email":"kifill0@livejournal.com","count":93,"ip_address":"182.218.153.253"}]'
OK
127.0.0.1:6379> DEBUG OBJECT a
Value at:0x7f98582b96f0 refcount:1 encoding:raw serializedlength:128 lru:11692490 lru_seconds_idle:2
127.0.0.1:6379> MEMORY usage a
(integer) 182
127.0.0.1:6379> set a '\x91\x86\xa5count]\xaafirst_name\xa7Kyrstin\xa9last_name\xa5Ifill\xa5email\xb7kifill0@livejournal.com\xaaip_address\xaf182.218.153.253\xa2id\x01'
OK
127.0.0.1:6379> MEMORY usage a
(integer) 197
127.0.0.1:6379> DEBUG OBJECT a
Value at:0x7f98582b9700 refcount:1 encoding:raw serializedlength:143 lru:11692517 lru_seconds_idle:6
127.0.0.1:6379> set a "\x91\x86\xa5count]\xaafirst_name\xa7Kyrstin\xa9last_name\xa5Ifill\xa5email\xb7kifill0@livejournal.com\xaaip_address\xaf182.218.153.253\xa2id\x01"
OK
127.0.0.1:6379> DEBUG OBJECT a
Value at:0x7f98582b96f0 refcount:1 encoding:raw serializedlength:107 lru:11692535 lru_seconds_idle:2
127.0.0.1:6379> MEMORY usage a
(integer) 158
答案 0 :(得分:0)
此答案基于Redis 4.0,位于64位计算机上
为了提高内存效率,Redis用三种方法对值字符串进行编码:
-2^63
〜2^63
,Redis将值保存为整数。这是最有效的编码。44
字节,Redis将字符串保存在同一块中Redis对象本身。这比Raw String
编码更有效。此外,它更适合缓存。在你的情况下:
set a 1
和set a "1"
:该值是一个可以转换为1
的字符串。因此,Redis使用 Int 编码,即encoding:int
。set a \x01
和set a '\x01'
:该值是一个包含4
个字符的字符串(注意:由于字符串用单引号括起来,因此不会被转义)。它不能转换为整数,其大小小于44
。因此,Redis使用 嵌入字符串 编码,即encoding:embstr
。set a "\x01"
:由于字符串用双引号括起来,因此该值将作为二进制字符串进行转义,其长度(即1
字节)小于44
,并且不能转换为整数。因此,Redis使用 嵌入字符串 编码,即encoding:embstr
。44
的字符串。因此,Redis使用 原始字符串 编码,即encoding:raw
。