我在 redis 数据库中存储了约 300M 个对象。该对象包括:
- 身份证
- 约会对象
- 一个包含 48 个值的数组
我使用 ID/日期作为键,我正在寻找存储 48 个值的最佳方式(内存使用)。
该值为整数,通常在 [1-1000] 之间。
我使用的第一种方法是在 Java 中构建对象并使用自动序列化对象的框架 (spring-data-redis)。
生成的格式类似于:
{\"@class\":\"com.mycompany.Points\",\"faceId\":1234,\"date\":[\"java.util.Date\",1509663600000],\"points\":[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 是什么?)。
我试图将它存储为一个列表:
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
有没有更合适的方式来存储这个数组?
最佳答案
It there a more apprioriate way to store this array?
这取决于您的 Redis 版本,但从 v3.2 开始,有令人难以置信的 BITFIELD
,如果您将它与无符号的 10 位字段(最接近 1000 的 2 的幂)一起使用,这就是适合您的东西。
注意: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 编码。
关于redis - 在 Redis 数据库中存储整数数组的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47100606/