redis五种数据结构特点

redis-string介绍SDS内部存储数据结构三种编码方式特点总结

redis-list介绍quicklist特点总结

redis-hash特点总结

redis-set介绍

特点总结redis-zset介绍特点总结

redis使用五种数据结构,分别是string(字符串),list(列表),hash(哈希表),set(集合),zset(有序列表)。

下面介绍他们的一些特点

redis-string

介绍

string是redis中最基础的数据结构,就是KV键值对中V值的类型是字符串。

SDS内部存储数据结构

redis没有使用char数组来存储字符串,而是使用SDS(simple dynamic string)来存储字符串。SDS是一种数据结构,定义为:

struct __attribute__ ((__packed__)) sdshdr32 {

uint32_t len; /* used */

uint32_t alloc; /* excluding the header and null terminator */

unsigned char flags; /* 3 lsb of type, 5 unused bits */

char buf[];

};

len属性表示当前字符串使用了len个字节; alloc属性表示分配到的总长度; flags代表字符串编码 buf用来存储具体数据,以’\0’结尾(保留这种设计是为了让SDS可以直接重用一部分C字符串函数库里面的函数)

相比于c字符串,SDS的优势:

SDS获取字符串长度的时间复杂度是O(1),c字符串是O(n);SDS在字符串长度增减时自动处理分配空间,杜绝内存溢出的操作;相比c字符串,减少了内存重分配的次数;SDS是二进制安全的。C字符串中的字符必须符合某种编码(比如ASCII),并且除了字符串的末尾之外,字符串里面不能包含空字符,否则最先被程序读入的空字符将被误认为是字符串结尾,这些限制使得C字符串只能保存文本数据,而不能保存像图片、音频、视频、压缩文件这样的二进制数据。而SDS不会出现因为特殊字符导致字符串被截断的问题,SDS的API都是二进制安全的(binary-safe),所有SDS API都会以处理二进制的方式来处理SDS存放在buf数组里的数据。

三种编码方式

redis为了更好的节省空间,采用不同方式的存储。

当保存的是 Long 类型整数时,RedisObject 中的指针就直接赋值为整数数据了,这样就不用额外的指针再指向整数了,节省了指针的空间开销。当保存的是字符串数据,并且字符串小于等于 44 字节时,RedisObject 中的元数据、指针和 SDS 是一块连续的内存区域,这样就可以避免内存碎片。这种布局方式也被称为 embstr 编码方式。当保存的是字符串数据,并且字符串大于 44 字节时,SDS 的数据量就开始变多了,Redis 就不再把 SDS 和 RedisObject 布局在一起了,而是会给 SDS 分配独立的空间,并用指针指向 SDS 结构。这种布局方式被称为 raw 编码模式。

特点总结

采用SDS数据结构进行存储,相比c字符串效率更高,更安全当字符串是long类型整数时,直接采用int格式存储;当字符串是<=44字节的字符串,采用embstr格式存储;当字符串是>44字节的字符串,采用raw格式存储;

redis-list

介绍

list在redis中代表一种可以双向插入,删除的链表。

quicklist

quicklist是redis中list使用的数据结构,它是由双向链表和ziplist组成的。 其主体是一个双向链表,链表中的每一个元素是一个ziplist,每当ziplist超过list-max-ziplist-size大小的时候(默认8字节),就会新建一个ziplist。 这样设计的好处是即保留了链表头尾插入,删除元素的高效,也使得中间元素的查询变得更加高效。

特点总结

采用quicklist进行存储

redis-hash

特点总结

redis中的hash使用ziplist和hashtable作为存储数据结构使用ziplist的条件: – key < 64 bytes – value < 64 bytes – 元素个数 < 521 – 否则就会使用hashtableredis中的hashtable是使用dictht实现的 其中,table 结构是一个 dictEntry 类型的数组,而 dictEntry 是一个单向链表中的节点,代表的是 hashtable 中的一条记录,包含了该条记录的 key、value 以及指向下一个节点(下一条记录)的指针(hash 碰撞)。 dictEntry 中的 key 和 val 都是 void 类型,意味着可以存储任意数据类型。所以,即使 Redis 中一些数据类型本身的底层实现也是 hashtable(set、zset、hash 等),但仍然可以存储在 redisDb 中的 dict 中。 dictht 中的 size 表示 hashtable 中 bucket 的数量,sizemask 是 size 的位掩码,用于计算对应的 key 应该存储在哪个 bucket 当中(位运算的效率高于取模运算)。而 used 则用来存储当前 hashtable 中实际存储的记录(元素)的数量。

redis-set

介绍

set在redis中代表无序集合,其中元素的key值不可以重复出现。

特点总结

set存储结构是两种:intset和hashtableintset使用条件: – V值类型是数字 – 元素个数 < 512 – 否则使用hashtable来存储

redis-zset

介绍

zset在redis中代表有序集合,其中元素key值不可以重复出现,按照给定的score排序

特点总结

zset使用ziplist和skiplist作为存储结构使用ziplist的条件: – 元素个数 < 128 – key < 64 bytes – value < 64bytes – 否则使用skiplist

文章来源

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。