[关闭]
@zero1036 2016-12-20T11:42:59.000000Z 字数 1365 阅读 3390

Redis内存优化--String And Hash

Redis


String与Hash

String与Hash毫无疑问是最常用的两种数据结构,而且AB两个方案互换使用往往都可以满足系统的业务需求,该如何选型,才能在复杂度、性能以及内存间取得一个平衡点?

举个例子,存储以下数据,分别采取String与Hash的形式:

* object:1
* object:2
* object:3
* object:……
* object:100000

String存储:以object:x作为key,(1)

![stringexp][4]

Hash存储:以object:x作为Key,后两位字节xx作为hash key,(2)

![hash100exp][5]

(1)存储结果:
![string10w][6]

(2)存储结果:
![hash100-10w][7]

从以上结果可以得出:hash散列比string更节省内存,原因有3点:

  1. Redis的Key承载了很多特性的,过期时间、LRU、Cluster节点信息、系统关键信息等,因此和String类型的key-value相比,hash类型可更大限度地减少key的数量,从而节省内存空间的使用率;
  2. key对应多种数据结构,而hash key对应的value只能是string,这种简单结构比多重复杂结构更加高效。(Redis是不支持嵌套数据的,例如hash中value还嵌套有hash);
  3. hash在额定数量及容积下,将会以一维线性的紧凑格式存储(ziplist),这种存储形式可节省更多空间。

注意一点是:hash只会在额定的要求范围内,才会以ziplist存储,当超过额定阈值后会转换成真正hashtable格式并重新存储。而hashtable的存储对于内存的使用不占优势。关于这个额定值,redis提供了两个可配置参数hash-max-ziplist-entrieshash-max-ziplist-value

* `hash-max-ziplist-entries`:hash以ziplist存储的最大对象数量,单位:个

* `hash-max-ziplist-value`:hash以ziplist存储的单个对象占用空间,单位:bytes

默认值是:

# Hashes are encoded using a memory efficient data structure when they have a
# small number of entries, and the biggest entry does not exceed a given
# threshold. These thresholds can be configured using the following directives.
hash-max-ziplist-entries 512
hash-max-ziplist-value 64

修改配置hash-max-ziplist-entries为20万,再调整以上例子写入10万数据到单一散列中,

![advconfig20w][8]

结果是,与(2)例子接近,以ziplist格式存储更节省空间,但缺点是ziplist格式读写速度相当低效,10万数据的写入花费了99356毫秒,接近1.5分钟。因此,在实际应用中,对应存储格式的选型,还是需要根据实际需求作为衡量标准。

![onehash10w][9]

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注