我需要你的一些建议。我试图以非常有效的方式使用redis和哈希(redis类型)存储一些数据。有一些随机字符串列表(平均大小为40个字符,但最大可能是rfc中的255个字符) - 它是文件ID,例如我们有100kk file_id列表。此外,我们需要为每个id跟踪2个参数:download_count(int,incrementmented)和server_id - tiny int, redis config添加:
hash-max-ziplist-entries 1024
首先,我们拒绝商店数据(palin text),巨大的开销:
file_id(40 byte) + download_count + server_id) * 100kk + redis pointers --no need to calculate at all.
其次,使用一些128位散列函数并按原样存储redis散列:但也有一些开销,但少于1。
最后我们得到类似的东西,使用redis hash:
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桶,所以此时我们可以通过link得到碰撞:(白内障与perit相撞),数据到达相同的桶,但是字段有crc32哈希,理论上我们理论上不能在这一点上发生碰撞(概率较小),理论上这个方案的碰撞阻力是否相等,例如64位散列?
但它不是真正有效的内存方案,所以我们可以得到这样的东西(有一个提交):
hmset(bucket, crc32(file_id as server_id_and_download_count_field), value1+’--’+value2)
所以我们不能使用递增函数,但是我们减少字段和内存使用,并且需要一些cpu来解析结果并用新值更新它(递增download_count),也许我们可以使用lua来制作一些内置的操纵这个?
所以我的问题: 它是强烈的抗冲突性(对于100kk数据)还是我们需要在字段(而不是crc32)中使用一些64位散列函数,但是当我们有10亿行时,对于这些数据来说足够强大了吗?
也许有更有效的计划?
谢谢!
答案 0 :(得分:0)
Redis哈希非常适合这个。看看我们看到的Redis doc for HSET
HSET myhash field1 "Hello"
我们还应该记住Redis是关于字符串的。我知道你在X字符之后将file_id
分开(比如10)并将第一部分用作myhash
,其余部分用作field1
。这样,您将所有以相同X字符开头的file_ids折叠为一个哈希,并且只需支付一次。因此,在myhash
上测试不同长度,看看哪个值对你有好处。
要做的第二件事是创建"Hello"
,你的价值。由于Redis喜欢字符串,因此您应该将所有数据编码为一个。从server_id
开始,因为您知道这个字节的大小,然后附加download_count
。如果您使用的是Python,则可以轻松使用struct.pack()
将其转换为字符串。
您还可以查看file_ids中是否存在所有字符。如果那些只是一个子集,你可以将它们编码为更密集的形式,也许可以节省几个字符。
祝你好运!