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

时间:2017-11-03 16:41:57

标签: 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

因此,如果我正确阅读,该条目在数据库中需要 206 (206 what?)。

我尝试将其存储为列表:

redis 127.0.0.1:6379> lpush dummy 1 2 3 4 5 [...] 48
(integer) 48

实际上,尺寸几乎相同:

redis 127.0.0.1:6379> DEBUG OBJECT dummy
Value at:0x7fce467c2800 refcount:1 encoding:ziplist serializedlength:205 lru:2074809 lru_seconds_idle:10

类型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]

尺寸减少到 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

有一种更适合存储此阵列的方法吗?

1 个答案:

答案 0 :(得分:12)

  

有一种更适合存储此阵列的方法吗?

这取决于你的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

对于早期版本的Redis,您可以探索使用Lua脚本并编写基于脚本的相同逻辑变体和/或尝试使用数组的MessagePack编码。