在Redis数据库中存储整数数组的最佳方法

Arn*_*lle 2 redis

我在redis数据库中存储~300M对象.该对象包括:

  • 一个ID
  • 一个约会
  • 一个由48个值组成的数组

我使用ID /日期作为键,我正在寻找存储48个值的最佳方式(内存使用).

值是整数,通常在[1-1000]之间.

我使用的第一种方法包括在Java中使用对象构建并使用自动序列化对象的框架(spring-data-redis).

结果格式如下:

{\ "@类\":\ "com.mycompany.Points \",\ "faceId \":1234,\ "日期\":[\ "java.util.Date \",1509663600000],\"点\ ":5,5,10,10,10,10,60,60,60,60,60,60,40,40,40,40,40,40,30,30,30,30,30,80 ,80,80,80,80,80,80,20,20,20,20,20,10,10,10,10,10,5,5,5,5,5,5,5,5]}

然后我使用此命令在redis中跟踪此对象的大小:

redis 127.0.0.1:6379> DEBUG OBJECT POINTS_215004#03-11-2017
Value at:0x7fce4b2b6ac0 refcount:1 encoding:raw serializedlength:206 lru:2074768 lru_seconds_idle:10
Run Code Online (Sandbox Code Playgroud)

因此,如果我正确读取它,数据库中的条目需要206(206什么?).

我试图将其存储为列表:

redis 127.0.0.1:6379> lpush dummy 1 2 3 4 5 [...] 48
(integer) 48
Run Code Online (Sandbox Code Playgroud)

实际上,尺寸几乎相同:

redis 127.0.0.1:6379> DEBUG OBJECT dummy
Value at:0x7fce467c2800 refcount:1 encoding:ziplist serializedlength:205 lru:2074809 lru_seconds_idle:10
Run Code Online (Sandbox Code Playgroud)

也许这种类型ziplist的内存消耗更多.

然后我尝试将其存储为纯字符串:

redis 127.0.0.1:6379> set dummy  [5,5,10,10,10,10,60,60,60,60,60,60,40,40,40,40,40,40,30,30,30,30,30,80,80,80,80,80,80,80,20,20,20,20,20,10,10,10,10,10,5,5,5,5,5,5,5,5]
Run Code Online (Sandbox Code Playgroud)

大小减少到53:

redis 127.0.0.1:6379> debug object dummy
Value at:0x7fce470b2dc0 refcount:1 encoding:raw serializedlength:53 lru:2074818 lru_seconds_idle:10
Run Code Online (Sandbox Code Playgroud)

它有更多的apprioriate方式来存储这个数组?

Ita*_*ber 12

它有更多的apprioriate方式来存储这个数组?

这取决于你的Redis版本,但是从v3.2开始就有了令人难以置信BITFIELD的东西,如果你将它用于无符号的10位字段(最接近2到1000的幂),那就是你的选择.

注意: DEBUG OBJECT输出不是测量Redis中密钥内存消耗的可靠方法 - serializedlength字段以持久化对象所需的字节数给出,而不是内存中包含各种管理开销的数据本身. .从v4开始,我们有MEMORY USAGE一个更好的工作命令 - 请参阅https://github.com/antirez/redis-doc/pull/851获取文档详细信息.

$ for i in {0..47}; do redis-cli BITFIELD dummy SET u10 \#$i $i; done
...
$ redis-cli
127.0.0.1:6379> strlen dummy
(integer) 60
127.0.0.1:6379> DEBUG OBJECT dummy
Value at:0x7f83e040e430 refcount:1 encoding:raw serializedlength:61 lru:16563203 lru_seconds_idle:27
127.0.0.1:6379> MEMORY USAGE dummy
(integer) 117
Run Code Online (Sandbox Code Playgroud)

对于较早版本的Redis,可以探讨使用Lua脚本的和组成相同的逻辑的基于脚本的变体和/或尝试使用该阵列的MessagePack编码.