以下是redis官网中给出的几点关于节省内存的tips,以下是部分摘要和个人理解,本人英语水平一般,有些翻译和理解错误的地方还望批评指正。
原文链接:http://redis.io/topics/memory-optimization
原文链接:http://redis.io/topics/memory-optimization
- Special encoding of small aggregate data types
从redis2.2之后,当一些数据结构超出了指定的范围,就会用一种很节省空间的方式来存储。
可以通过设置redis.conf中的这些值来配置该选项。
hash-max-zipmap-entries 64 (hash-max-ziplist-entries for Redis >= 2.6) hash-max-zipmap-value 512 (hash-max-ziplist-value for Redis >= 2.6) list-max-ziplist-entries 512 list-max-ziplist-value 64 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 set-max-intset-entries 512
- Using 32 bit instances
用32位的来编译会比较节省内存,因为用来实现redis内部功能的指针所占用的内存会比较小
(Redis compiled with 32 bit target uses a lot less memory per key, since pointers are small)
- Bit and byte level operations
尝试使用bit、byte级别的value来存储数据。如需要保存一个user对象,可以用一个位来存储性别信息。当设置了这一位时,表示 男性,当擦除了这一位时,表示女性。另外,可以使用setrange和getrange来在一个字节里存储信息。如,某个字节第1-10位表示姓名, 第11-20位表示年龄等。
- Use hashes when possible
redis官网强烈建议使用hash来存储数据。例如,表示一个user对象,我们可以这样来设计:
key: zhangsan:age
value: 35
key: zhangsan:city
value: beijing
但是redis建议不要这样设计,而是应该这样设计:
key: zhangsan
value: <"age", 35>
<"city", "beijing>
也就是使用一个map作为key
这样设计会节省很多内存。但是有人可能会问,hash类型的value会不会比string类型的value更耗费性能?在高并发的情况下hash类型的 value是不是会表现的比较差。
这里是这样给出的解释:
当hash中value值很小时,redis会自动将其存储为一个很高效的形式(encode them in an
O(N) data structure, like a linear array with length-prefixed key value pairs),这样当调用HGET和HSET方法时,复杂度仍然是O(1)的。当value值超过阈值的时候,就会转变成真正的hash结构,这样一来,确实会对性能造成一定的损耗。这个阈值可以通过设置这两个选项来改变:
hash-max-zipmap-entries 256
hash-max-zipmap-value 1024
尽管如此,redis还是希望设计者能够尽量使用hash的存储结构,它是这样说明的(这一段我没有看的太明白,貌似没有详细解释关于效率的 这个问题,希望看明白的人能一起讨论一下):
However since hash fields and values are not (always) represented as full featured Redis objects, hash fields can't have an associated time to live (expire) like a real key, and can only contain a string. But we are okay with this, this was anyway the intention when the hash data type API was designed (we trust simplicity more than features, so nested data structures are not allowed, as expires of single fields are not allowed).
最后,文章中做了一个总结,意思是说如果转变成hash方式存储了,节省内存的优势就没有了。redis这样设计有两个原因:
1、能够让开发者在CPU、memory和最大元素个数这些因素之间做一个权衡,从而能够根据自己的应用进行灵活配置
2、最外层的key空间应该是能够支持一些全局的key,例如expires, LRU data等,所以不应该用业务键来作为最外层的key