实现
hash数据结构底层实现为一个字典(dict),也是redisDb用来存储k-v的数据结构,当数据量比较小,或者单个元素比较小时,使用ziplist存储,数据大小和元素数量阈值可以通过如下参数设置
数量阈值
hash-max-ziplist-entries 512
数据大小
hash-max-ziplist-value 64
实验
127.0.0.1:6379> hmset u:001 username qqqwww age 100 k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> hgetall u:001
1) "username"
2) "qqqwww"
3) "age"
4) "100"
5) "k1"
6) "v1"
7) "k2"
8) "v2"
9) "k3"
10) "v3"
127.0.0.1:6379> object encoding u:001
"ziplist"
当存储的k-v长度较小时,底层是以ziplist存储,hgetall顺序与hmset顺序一致,存储数据内存是连续的,
在ziplist中,每一个key和value都用一个entry进行存储,hgetall的时候,遍历ziplist一次性把数据取出。
127.0.0.1:6379> hmset u:001 username qqqwww age 100 k1 v1 k2 v2 k3 v3 k4 vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
OK
127.0.0.1:6379> hgetall u:001
1) "k4"
2) "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv"
3) "k1"
4) "v1"
5) "age"
6) "100"
7) "k2"
8) "v2"
9) "username"
10) "qqqwww"
11) "k3"
12) "v3"
127.0.0.1:6379> object encoding u:001
"hashtable"
然后存储一个key为k4,value为比较大的值之后,底层存储数据结构换成了hashtable。
Redis中提供两个参数设置
# 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 512 表示当k-v数量小于512/2 = 256时,使用ziplist进行存储。
hash-max-ziplist-value 64 表示当其中一个key或value值大于64字节,就会将存储方式从ziplist改成hashtable。
使用ziplist好处
本身hashtable结构的开销就比较大,当hash结构存储的k-v不多,或者k-v的值比较小时,直接用hashtable存储会比较浪费,用ziplist则可以高效利用内存。
与string类型比较
hash只能给key设置过期时间,不能给某一个field设置,hash中如果有某些长期不用,也不会自动释放。
string类型是直接在db最外层上进行key的设置,当key达到hashtable容量时,会产生成倍扩容,需要额外更多的空间。
网友评论