我有一个键,它是由许多不同的元素连接而成的
[15000个唯一字符串]+[:]+[5个唯一字符串]+[:]+[1或0]+[:]+[15000个独特字符串]+[:]+[1或0]=长度在20到50个字符之间的字符串(例如:温哥华:临时:1:Kelowna:高:0)
根据我的计算,将有大约10亿个组合,每个组合都将是一个关键。阅读redis文档(http://redis.io/topics/memory-optimization)他们建议您散列密钥:例如,"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之间的一位数或两位数整数。
查找表完全用完了,甚至不用麻烦。哈希解决方案似乎非常适合您的需求。你会希望你的密钥在15000次独特的刺痛之前被分开,给你足够的哈希密钥,让它值得付出努力。
所以不是:
SET Vancouver:temp:1:Kelowna:high:0 10
你会使用
HSET Vancouver:temp:1 Kelowna:high:0 10
现在,第一个[1或0]之后的所有内容都将是一个哈希密钥,因此每个哈希大约有150000个可能的密钥。
我对你的总密钥空间的计算与你的有所不同:
15000 * 5 * 2 * 15000 * 5 * 2 == 22500000000 (22.5 billion)
因此,通过这种方式,您将有150000个可能的密钥(redis密钥),每个密钥有150000个哈希密钥。
redis键和哈希键之间的间隔越左,哈希键的数字偏移就越大。例如,如果你像一样把它分解
HSET Vancouver:temp 1:Kelowna:high:0 10
然后,您将有75000个redis密钥用于哈希,每个哈希可能包含300000个密钥/值对。
另一种方法是使用整数值作为键。如果您的两组15000个唯一字符串和5个唯一字符串中的每一个都有整数映射,那么您可以使用总共34位来表示任何键。例如
0000000000000 000 0 0000000000000 000 0
| 13 | | 3 | |1| | 13 | | 3 | |1|
13位的范围为0-16383(涵盖所需的1-15000)3位为您提供0-7的范围(包括所需的1-5)1位为您提供所需的二进制1或0范围。
因此,假设这些虚构的值:Vancuver==9987温度==3Kelowna==3454高=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