gpt4 book ai didi

redis 减少 20-50 个字符长度的字符串键的内存消耗

转载 作者:IT王子 更新时间:2023-10-29 06:01:37 25 4
gpt4 key购买 nike

我有一个键是通过连接许多不同的元素生成的。:

[15,000 个唯一字符串] + [:] + [5 个唯一字符串] + [:] + [1 或 0] + [:] + [15,000 个唯一字符串] + [:] + [5 个唯一字符串] + [ :] + [1 or 0] = 长度在 20 到 50 个字符之间的字符串(例如:Vancouver:temp:1:Kelowna:high:0)

根据我的计算,将有大约 10 亿种组合,每种组合都是一把 key 。阅读 redis 文档(http://redis.io/topics/memory-optimization),他们建议您散列 key :例如。 "object:11558960"=> "1"可以变成 "object:1155""8960"=> "1"。

我正在考虑应用内存优化的最佳方法。我的第一个想法是为字符串创建一个数字表示。所以我会使用 MySQL 并创建查找表,其中每个字符串都有一个对应的数字整数。这样我可以更适本地散列,因为我可以比字符串更容易地划分数字。同样,这些数字会创建更短的键,我认为这会节省内存。这里的问题是 10 亿个键,这对 MySQL 来说是很大的开销,因为我必须创建连接等等。

我读到的另一种解决方案是获取我创建的字符串,然后在插入到 redis 之前使用 php 的 gzcompres 之类的工具对其进行压缩。 (http://labs.octivi.com/how-we-cut-down-memory-usage-by-82/)。

是否有任何最佳实践优化我可以用来降低我的 redis 内存消耗,因为目前它仍然太高?我愿意放弃 CPU 的能力来节省更多的内存。我的值只会是 0-50 之间的一位或两位整数。

最佳答案

查找表完全出问题了,别费心了。哈希解决方案似乎很适合您的需求。您可能希望您的 key 在 15,000 个唯一字符串之前立即拆分,以便为您提供足够的哈希 key ,使它值得付出努力。

所以代替:

SET Vancouver:temp:1:Kelowna:high:0 10

你会用

HSET Vancouver:temp:1 Kelowna:high:0 10

现在第一个 [1 或 0] 之后的所有内容都是哈希键,因此每个哈希大约有 150,000 个可能的键。

我对你的总 key 空间的计算与你的有点不同:

15000 * 5 * 2 * 15000 * 5 * 2 == 22500000000 (22.5 billion)

这样一来,您将拥有 150,000 个可能的键(redis 键),每个键都有 150,000 个可能的哈希键。

你在 redis key 和 hash key 之间做的间隔越靠左,hash key 的数字倾斜度就越大。例如,如果您将其拆分为

HSET Vancouver:temp 1:Kelowna:high:0 10

那么您将拥有 75,000 个用于散列的 Redis 键,每个散列可能包含 300,000 个键/值对。


另一种方法是使用整数值作为 key 。如果您的两组 15,000 个唯一字符串和 5 个唯一字符串中的每一个都有整数映射,那么您可以使用总共 34 位来表示任何 key 。例如。

 0000000000000   000   0   0000000000000   000   0
| 13 | | 3 | |1| | 13 | | 3 | |1|

这 13 位给出了 0-16383 的范围(涵盖了所需的 1-15,000)这 3 位给出了 0-7 的范围(涵盖了所需的 1-5)1 位为您提供所需的二进制 1 或 0 范围。

所以假设这些组成的值:温哥华 == 9,987温度== 3基洛纳 == 3,454高 = 2

你会:

(9987 << 21) + (3 << 18) + (1 << 17) + (3454 << 4) + (2 << 1) + (0 << 0)
==
20945229796

要从给定的键中取回值,您只需进行位移和屏蔽

20945229796 >> 20
9987

(20945229796 >> 4) & ((1 << 13) - 1)
3454

这是一个简单的 python 脚本,它将值转换为 int,并将 int 转换为值:

values = [9987, 3, 1, 3454, 2, 0]
bits = [21, 18, 17, 4, 1, 0]

value_and_shift = zip(values, bits)


def key_from_values(values_and_shift):
return sum(x << y for x, y in value_and_shift)

def extract_values(values_and_shift):
last_shift = 35
for value, shift in value_and_shift:
print "Value should be:", value
print "Value extracted:", (key >> shift) & ((1 << (last_shift - shift)) - 1)
print
last_shift = shift

key = key_from_values(value_and_shift)
print "Using value of:", key

extract_values(value_and_shift)

输出

Using value of: 20945229796

Value should be: 9987
Value extracted: 9987

Value should be: 3
Value extracted: 3

Value should be: 1
Value extracted: 1

Value should be: 3454
Value extracted: 3454

Value should be: 2
Value extracted: 2

Value should be: 0
Value extracted: 0

关于redis 减少 20-50 个字符长度的字符串键的内存消耗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25858461/

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