Redis高效存储数据(散列)

Redis高效存储数据(散列),redis,hashtable,collision-detection,hash-function,collision,Redis,Hashtable,Collision Detection,Hash Function,Collision,我需要你的建议。我试图用redis和Hash(redis类型)以非常节省内存的方式存储一些数据。有一些随机字符串列表(平均大小为40个字符,但rfc中最大可能为255个字符)——它是文件id,例如,我们有100kk文件id列表。我们还需要为每个id设置两个参数:下载计数(int,递增)和服务器id——微小int, redis配置添加了: hash-max-ziplist-entries 1024 首先,我们拒绝按原样存储数据(佩林文本),这会带来巨大的开销: file_id(40 byte)

我需要你的建议。我试图用redis和Hash(redis类型)以非常节省内存的方式存储一些数据。有一些随机字符串列表(平均大小为40个字符,但rfc中最大可能为255个字符)——它是文件id,例如,我们有100kk文件id列表。我们还需要为每个id设置两个参数:下载计数(int,递增)和服务器id——微小int, redis配置添加了:

hash-max-ziplist-entries 1024
首先,我们拒绝按原样存储数据(佩林文本),这会带来巨大的开销:

file_id(40 byte) + download_count + server_id) * 100kk + redis pointers --no need to calculate at all.
第二,使用一些128位的散列函数,并按redis散列的原样存储:但也有一些开销,但小于1

最后,通过redis哈希,我们得到了如下结果:

hmset(bucket, server_id_field, value1, download_count_filed, value2), 
server_id_field = crc32(file_id)
download_count_filed = crc32(file_id) + 1,
bucket = murmur2(file_id) div 10^5
所以总共有100k个存储桶,所以在这一点上我们可以得到碰撞,例如:(白内障与腹膜碰撞)由于,数据得到相同的存储桶,但字段有crc32哈希,理论上我们在这一点上不能得到碰撞(概率较小),从理论上讲,该方案的抗冲突能力是否与例如64位哈希相同

但它并不是真正有效的内存方案,所以我们可以得到类似的结果(只有一个字段):

所以我们不能使用增量函数,但我们减少了字段和内存使用,并且需要一些cpu来解析结果并用新值(增量下载计数)将其更新回来,也许我们可以使用lua来进行一些内置操作

所以我的问题是: 它是否具有很强的抗冲突性(对于100kk数据),或者我们可能需要在字段中使用一些64位哈希函数(而不是crc32),但是当我们有10亿行的数据足够强大时,该怎么办

也许有更有效的方案


谢谢大家!

Redis散列非常适合这种情况。看看我们看到的

我们还应该记住,Redis是关于字符串的。我建议您在X个字符(比如10个字符)后拆分
文件id
,并将第一部分用作
myhash
,其余部分用作
field1
。通过这种方式,您可以将所有以相同X字符开头的文件ID折叠为一个哈希,并且只需支付一次。因此,在
myhash
上使用不同的长度进行测试,看看什么值对您有利

第二件事是创建
“Hello”
,即您的值。因为Redis喜欢字符串,所以您应该将所有数据编码为一个字符串。从
server\u id
开始,因为您知道它的大小(以字节为单位),然后追加
download\u count
。如果您使用的是Python,那么可以轻松地使用
struct.pack()
将其转换为字符串

您还可以查看文件ID中是否存在所有字符。如果这些只是一个子集,您可以将它们编码成更密集的形式,并可能节省一些字符

祝你好运

hmset(bucket, crc32(file_id as server_id_and_download_count_field), value1+’--’+value2)
HSET myhash field1 "Hello"