gpt4 book ai didi

redis - 在 Redis 有序集中存储整数?

转载 作者:IT王子 更新时间:2023-10-29 05:54:59 25 4
gpt4 key购买 nike

我有一个系统可以处理已变成无符号长整数的键(通过将短序列打包成字节串)。我想尝试将这些存储在 Redis 中,并且我想以尽可能最好的方式进行。我主要关心的是内存效率。

通过玩在线 REPL,我注意到以下两个是相同的

zadd myset 1.0 "123"

zadd myset 1.0 123

这意味着即使我知道我要存储一个整数,它也必须设置为一个字符串。我从文档中注意到, key 仅存储为 char* 并且命令类似于 SETBIT表明 Redis 不反对在客户端将字符串视为字节串。这暗示了一种存储 unsigned long 的方式比它们的字符串表示形式稍微更有效。

在有序集合中存储 unsigned long 的最佳方式是什么?

最佳答案

感谢安德烈的回答。这是我的发现。

直接存储整数

Redis 键必须是字符串。如果你想传递一个整数,它必须是某种字符串。对于小的、定义明确的值集,Redis 会将字符串解析为整数(如果是整数)。我的猜测是它将使用这个 int 来定制它的散列函数(或者甚至基于值静态地确定散列表的维度)。这适用于小值(示例是 64 个条目的默认值,最大值为 512)。我将在调查期间测试更大的值。

http://redis.io/topics/memory-optimization

存储为字符串

另一种方法是压缩整数,使其看起来像一个字符串。

看起来可以使用任何字节串作为键。

对于我的应用程序而言,存储字符串或整数实际上并没有太大区别。我想 Redis 中的结构无论如何都会进行某种对齐,因此无论如何可能会有一些预先浪费的字节。在任何情况下,该值都会被散列。

使用 Python 进行测试,因此我能够使用 struct.pack 创建值。 long long 有 8 个字节,相当大。鉴于整数值的分布,我发现存储字符串实际上可能是有利的,尤其是在以十六进制编码时。

因为 redis 字符串是“Pascal 风格”的:

struct sdshdr {
long len;
long free;
char buf[];
};

考虑到我们可以在其中存储任何内容,我做了一些额外的 Python 代码以将类型编码为尽可能短的类型:

def do_pack(prefix, number):
"""
Pack the number into the best possible string. With a prefix char.
"""

# char
if number < (1 << 8*1):
return pack("!cB", prefix, number)

# ushort
elif number < (1 << 8*2):
return pack("!cH", prefix, number)

# uint
elif number < (1 << 8*4):
return pack("!cI", prefix, number)

# ulonglong
elif number < (1 << 8*8):
return pack("!cQ", prefix, number)

这似乎节省了微不足道的(或根本没有)。可能是由于 Redis 中的结构填充。这也使 Python CPU 飞速发展,使其有点没有吸引力。

我正在处理的数据是 200000 个 连续整数 =>(权重,随机整数)× 100 的 zsets,加上一些倒排索引(基于随机数据)。 dbsize 产生 1,200,001 个键。

服务器的最终内存使用:1.28 GB RAM,1.32 虚拟内存。各种调整使两种方式的差异不超过 10 兆字节。

所以我的结论是:

不要费心编码成固定大小的数据类型。只需将整数存储为字符串,如果需要,可以使用十六进制。它不会有太大的不同。

引用资料:

http://docs.python.org/library/struct.html

http://redis.io/topics/internals-sds

关于redis - 在 Redis 有序集中存储整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7973228/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com