Redis - hash底层数据结构实现

2021-04-07  本文已影响0人  kyo1992

实现

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容量时,会产生成倍扩容,需要额外更多的空间。

上一篇 下一篇

猜你喜欢

热点阅读