zipmap优化hash以hash类型存储一个对象会占用更少的内存,可以更方便的访问整个对象。节省内存的原因是zipmap用于存储一个新的哈希对象。这个zipmap其实并不是一个hash表,但是和普通的hash实现相比,zipmap可以节省很多hash本身需要的元数据存储开销。虽然zipmap的增删改查都是O(n),但是一般对象的字段数并不会太大。所以使用zipmap也是很快的,也就是说增删改查平均还是O(1)。如果字段或值的大小超过一定的限制,redis会自动在内部用正常的哈希实现替换zipmap。这个限制可以在配置文件中指定(默认配置在redis根目录下的redis.conf中):hash-max-zipmap-entries512#configurationfieldupto512hash-max-zipmap-value64#configurationvalue***为64字节的ziplist优化列表如果redisObject的类型成员值为REDIS_LIST类型,则当列表中的元素个数小于配置值list-max-ziplist-entries时,元素值字符串的长度小于配置值list-max-ziplist-value可以编码成REDIS_ENCODING_ZIPLIST类型存储,否则存储在Dict中(Dict其实是HashTable的一种实现),list使用ziplist数据结构来存储数据,在一个一方面,这是为了节省内存,另一方面,这种结构化的顺序存储结构可以更好地利用cpulocal和prefetch策略。配置如下:list-max-ziplist-entries512#配置元素个数最多为512list-max-ziplist-value64#配置value***为64字节intset优化set当set集合中的元素为整数时且元素个数小于配置的set-max-intset-entries值时,使用intset数据结构存储,否则转为Dict结构。Dict实际上是HashTable的一种实现。key是元素值,值为NULL,所以可以用(1)判断某个元素在一定时间内是否包含在集合中。intset中的数组分为三种类型:int16_t类型、int32_t类型和int64_t类型。至于如何选择数组的类型,是根据存储值的取值范围来决定的。初始化时为int16_t,集合中的最大值为[INT16_MIN,INT16_MAX],[INT32_MIN,INT32_MAX],[INT64_MIN,INT64_MAX]动态判断整个数组的类型。例如,集合一开始是int16_t类型,当集合中加入[INT32_MIN,INT32_MAX]范围内的值时,存储集合的数组将升级为int32_t数组。intset元素限制的配置如下:set-max-intset-entries512#配置元素个数最多为512sortedset的元素个数和元素个数当大小小于某个限制时,使用ziplist存储。这个限制的配置如下:zset-max-ziplist-entries128#配置元素个数最多为512zset-max-ziplist-value64#配置value***为64字节总结Redis提供了很多优化内存的方式,以上这些配置的值都是默认配置,需要根据我们具体的需求场景进行调整,需要做大量的测试才能达到最好的效果。同时,你必须对Redis的这些数据结构有很好的了解。
