Redis Hash底层结构

redis的hash底层是由两种数据结构实现的

  1. hashtable

  2. ziplist

其中ziplist是redis的一种节省空间的数据结构,类似数组拥有连续空间,不同于数组的是,数组中的数据都是具有相同长度,ziplist中的每一个数据长度可以不同,具体的可以看下ziplist的实现

本篇文章看下我们在使用hash存数据的时候,redis是如何使用这两种数据结构的

1
2
3
4
5
# 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

也就是ziplist-entries的最大值不超过512(这里是指key-value对,也就是entry数据项为1024) 同时 ziplist-value(这里是指任意key或者value的长度)不超过64的情况下,redis内部会使用ziplist来进行存储,其中有一个超过以后就会变为hashtable,我们可以适当调整这个参数以满足我们具体业务需求,但是也不能无限制调大,因为虽然ziplist会节省空间,但是查询没有hashtable快,有利也有弊,注意权衡。

下面我们实际操作,来验证一下

1
2
3
4
5
6
7
8
redis:6379> hset key1 abcdefjhijklmnopqrstuvwxyzabcdefjhijklmnopqrstuvwxyz012345678964 lengthofkeyis64
(integer) 1
redis:6379> object encoding key1
"ziplist"
redis:6379> hset key1 abcdefjhijklmnopqrstuvwxyzabcdefjhijklmnopqrstuvwxyz0123456789645 lengthofkeyis65
(integer) 1
redis:6379> object encoding key1
"hashtable"

可以看到最开始key的长度为64的时候,底层使用ziplist的,当我们把长度改为65,就变为hashtable了

再验证下hash-max-ziplist-entries

1
2
3
4
[xxx@localhost]# redis-cli -h 127.0.0.1 -p 6379 -n 2 hgetall hashtest | wc -l
1024
redis:6379> object encoding hashtest
"ziplist"

再增加一对

1
2
3
4
[xxx@localhost]# redis-cli -h 127.0.0.1 -p 6379 -n 2 hgetall hashtest | wc -l
1026
redis:6379> object encoding hashtest
"hashtable"

我们在使用的时候合理的设置配置文件参数,选择合适的数据结构来存储。

Comments