1、Hashes, Lists, Sorted Sets、元素是integers的Sets ,对于这四种集合类型,当它们的元素数量和元素的大小 不超过配置值时,reids会以一种特殊的编码保存,最多可以节省10倍空间,平均可以节省5倍空间。下面是相应的配置

hashs类型配置
hash-max-zipmap-entries 512 (hash-max-ziplist-entries for Redis >= 2.6)
hash-max-zipmap-value 64  (hash-max-ziplist-value for Redis >= 2.6)

list类型配置
list-max-ziplist-entries 512
list-max-ziplist-value 64

sort set类型配置
zset-max-ziplist-entries 128
zset-max-ziplist-value 64

元素都是integer的set类型配置
set-max-intset-entries 512

2、使用32位的redis实例。32位的redis实例保存keys的空间会比64位的节省很多。但是32位的redis实例最多只能使用4G的内存空间。不过因为RDB和AOF持久化文件对于32位和64位的redis实例都是通用的,所以相互直接的迁移并不存在问题。

 

3、位和字节操作

redis提供的有位和字节级别的操作命令,位级别的命令是GETBIT 和 SETBIT,字节级别的命令是GETRANGESETRANGE。使用这些命令可以对string类型的值进行位操作。比如当想标记系统中的每个用户是否已经审核通过的时候,如果审核通过就把userId对应的那一位设为1,否则就是0。这样会比保存很多个key-value节省很多空间。

4、当hashes类型的值中包含的元素数量和元素的大小都不超过配置值时,reids会优化保存的编码,使用更小的内存。

hashs类型配置
hash-max-zipmap-entries 512 (hash-max-ziplist-entries for Redis >= 2.6)
hash-max-zipmap-value 64  (hash-max-ziplist-value for Redis >= 2.6)

所以在满足上述配置的情况下,尽可能的把多个key-value的存储形式改成以hashes数据类型存储,可以节省内存。但需要注意的是如果业务上要求key设置过期时间时,就没办法使用hashes保存了,因为hashes的field不支持设置过期时间。

举个例子,如果现在系统中有若干个下面这种形式的key, 我们想把它们保存成hashes类型的数据。一个hashes值保存100个对应的key-value值。

  • object:102393
  • object:1234
  • object:5

每次我们set一个值的时候,就把key分成两部分,一部分用作key,另一部分用作hashes值的fieldname。例如"object:1234"被分成两部分:

第一部分是除了最后两位数的剩余部分:  "object:12"

第二部分是最后两位数: "34"

最后的命令就是  HSET object:12 34 somevalue

如果最后只有一位或两位数字,如"object:5",那么就直接把最后的一位数字或两位数字当做fieldname

第一部分是: "object:"

第二部分是:"5"

这样每个hashes值都会保存100个元素。

最后,要根据key-value的size,设置hash-max-zipmap-value,根据每个hashes保存的field数量设置hash-max-zipmap-entries。

一旦hashes的元素大小或数量超过了设置的值,那么节省的内存就没啦。