redis - 在 Redis 数据库中存储整数数组的最佳方式

标签 redis

我在 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/

相关文章:

python - 如何使用python获取所有存储在redis中的数据库

asp.net-mvc-4 - 如何在主机服务器中配置多个 Redis 端口

node.js - 如何在具有多个 Node 和 socket.io-redis 的 socket.io 中检查套接字是否处于事件状态(已连接)

具有 Multi-Tenancy 的 Spring Data Redis

session - 具有并发用户许可的 Redis session

.net - Serilog Sinks Redis 是否支持 netcore 1.x?

ruby-on-rails - rails 和 node.js 之间的共享身份验证与 redis 存储

python - 我应该使用哪种数据库模型在运行时动态修改实体/属性?

multithreading - 启用事务支持后,spring-data-redis 连接是否未正确释放?

ruby-on-rails - 无法在同一 VPC 上将 aws redis 与 ec2 连接