它支持存储string(字符串)、list(链表)、set(集合)、zset(sorted set有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove以及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。
Redis中数据对象的定义如下:
typedef struct redisObject {
unsigned type:4;
unsigned encoding:4;
unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */
int refcount;
void *ptr;
} robj;
链表(List),哈希(Hash),有序集合(Sorted Set)在成员较少,成员值较小的时候都会采用压缩列表(ZIPLIST)编码方式进行存储。
这里成员"较少",成员值"较小"的标准可以通过配置项进行配置:
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
压缩列表简单来说就是一系列连续的内存数据块,其内存利用率很高,但增删改查效率较低,所以只会在成员较少,值较小的情况下使用。
其典型结构如下:
area |<---- ziplist header ---->|<----------- entries ------------->|<-end->|
size 4 bytes 4 bytes 2 bytes ? ? ? ? 1 byte
+---------+--------+-------+--------+--------+--------+--------+-------+
component | zlbytes | zltail | zllen | entry1 | entry2 | ... | entryN | zlend |
+---------+--------+-------+--------+--------+--------+--------+-------+
^ ^ ^
address | | |
ZIPLIST_ENTRY_HEAD | ZIPLIST_ENTRY_END
|
ZIPLIST_ENTRY_TAIL
area |<------------------- entry -------------------->|
+------------------+----------+--------+---------+
component | pre_entry_length | encoding | length | content |
+------------------+----------+--------+---------+
在Redis 3.2版本之前,一般的链表使用LINKDEDLIST编码。
在Redis 3.2版本开始,所有的链表都是用QUICKLIST编码。
两者都是使用基本的双端链表数据结构,区别是QUICKLIST每个节点的值都是使用ZIPLIST进行存储的。
整数集合(intset)是集合键的底层实现之一:
当一个集合只包含整数值元素, 并且这个集合的元素数量不多时, Redis 就会使用整数集合作为集合键的底层实现。
字典是Redis中存在最广泛的一种数据结构不仅在哈希对象,集合对象和有序结合对象中都有使用,而且Redis所有的Key,Value都是存在db->dict这张字典中的。
Redis 的字典使用哈希表作为底层实现。
一个哈希表里面可以有多个哈希表节点,而每个哈希表节点就保存了字典中的一个键值对。
Redis计算Hash值和索引的方式为:
hash = dict->type->hashFunction(key);
index = hash & dict->ht[x].sizemask;
更多请详见:https://yq.aliyun.com/articles/63461?spm=5176.154649.801568.8.kNutr4