Redis - 基础数据结构

Software Development 专栏收录该内容
57 篇文章 0 订阅

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net

Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。

Redis提供了更加丰富的数据结构和命令,它支持基于列表、集合、哈希表等多种数据结构。这些结构在redis中是由6种底层数据结构来实现:

简单动态字符串(SDS)
链表
字典
跳跃表
整数集合
压缩列表


SDS

用来保存redis数据库中的字符串,它是一个结构体:


结构体中的三个属性分别用来表示已使用的字节数量、未使用的字节数量、字节数组,redis之所以设计这个结构而不使用C语言中的字符串,是因为SDS结构相比C语言中的字符串有如下优点:

记录了字符串的长度,执行strlen操作时,复杂度为O(1),而普通字符串为O(n)。
SDS采用预先分配和惰性释放的优化策略,减少重新分配空间的次数,其中有free字段记录未使用空间字节数。
二进制安全,除了可以存储字符还可以存储任意二进制。
SDS操作函数会自动检查空间是否足够并且空间不足时自动扩展空间,从而防止内存溢出。

链表

用来存储链表结构数据,它被用来实现SADD等集合命令:


字典

字典在Redis中应用非常广泛,Redis数据库本身就是使用字典来作为底层实现的,比如我们执行命令:SET msg "hello world",redis就会在数据库中创建一个键为msg值为"hello world"的字典。

字典在实现上包含两个hash表,常规状态下,只有第一个hash表存储数据,当发生rehash时,会给第二个hash表分配空间,并且把第一个hash表中的数据拷贝到第二个hash表中。如果hash表中的数据量比较大时,会采用渐进式rehash,分多次完成,字典中有个rehashindex字段记录rehash进度(如果当前未进行rehash值为-1),这样的话在字典中查询数据时,可能会查找两个hash表,先查第一个表,如果查不到再查第二个,但是新增的数据都会添加到第二个hash表中,发生rehash之后会由第二hash表负责查询客户端请求数据。当服务器正在执行BGSAVE、BGREWRITEAOF等耗CPU的命令时,会尽量避免rehash操作。


跳跃表

redis实现了一个跳跃表结构,跳跃表被用来实现缓存中的有序集合如ZADD等命令。

整数集合

当集合中只包含整数时,并且集合中的元素数量不多时,redis会采用整数集合当作底层实现。


其中contents中的元素有可能是16、32、64字节,redis只会分配合适的内存,比如当前添加的时16位的整数,那么只会给contents元素分配16字节,后续往数组中再次添加16字节以上的整数时,会给该数组升级重新分配32或64字节内存,数组只能升级不能降级,能从16字节升级到32或64字节,但是不能从64字节降级到16或32字节。

压缩列表

当列表、集合、hash表、有序集合等结构中的元素数量小于某个阀值,redis会采用压缩列表当作这些结构的底层实现,目的是为了节省内存,压缩列表包含了下列各个组成部分:

zlbytes 4字节,纪录整个压缩列表占用的内存字节数:在对压缩列表进行内存重分配,或计算zlend时使用。
zltail 4字节,纪录压缩列表表尾节点距离压缩列表的起始地址有多少个字节,通过这个偏移量程序可以无须遍历整个压缩列表就可以确定表尾节点的地址。
zllen 2字节,纪录压缩列表包含的节点数量,当属性值等于UINT16_MAX时,结点的真实数量需要遍历整个压缩列表才能计算得出。
entryX,列表节点,长度由结点中的内存结点,结点中有个字段previous_entry_length记录了前一个几点的长度,当结点的长度在254左右时,对某结点的修改可能会引发所有结点的连锁更新。


压缩列表会节约内存,但是访问或修改结构中的元素时会损失一些性能,所以当元素数量或者元素大小超过了某个阀值之后会对值对象进行编码转换,转换成集合、hash表、有序集合等结构,并重新分配内存。

对象

Redis并没有直接使用上面那些数据结构来实现键值对数据库,而是在这些数据接口的基础上创建了一个对象系统,每次在Redis数据库中新创建一个键值对时,至少会创建两个对象,一个键对象,一个值对象。每个对象都包含指定的类型和编码。

对象类型

对象的type属性设置,可以通过TYPE命令来输出对象的类型,对象有下面几种类型:

字符串对象:类型常量为REDIS_STRING,输出值string。
列表对象:类型常量为REDIS_LIST,输出值list。
哈希对象:类型常量为REDIS_HASH,输出值hash。
集合对象:类型常量为REDIS_SET,输出值hash。
有序集合表对象:类型常量为REDIS_ZSET,输出值zset。
对象编码

对象的encoding属性设置,可以通过OBJECT ENCODING命令查看对象的编码,对象有下面几种编码:

long类型整数,REDIS_ENCODING_INT,输出int
embstr编码的SDS,REDIS_ENCODING_EMBSTR,输出embstr。embstr编码是专门用于保存短字符串的一种优化编码方式,跟正常的字符编码相比,字符编码会调用两次内存分配函数来分别创建redisObject和sdshdr结构,而embstr编码则通过调用一次内存分配函数来分配一块连续的空间,空间中一次包含redisObject和sdshdr两个结构
SDS,REDIS_ENCODING_RAW,输出raw
字典,REDIS_ENCODING_HT,输出hashtable
双端链表,REDIS_ENCODING_LINKEDLIST,输出linkedlist
压缩列表,REDIS_ENCODING_ZIPLIST,输出ziplist
整数集合REDIS_ENCODING_INISET,输出intset
跳跃表和字典,REDIS_ENCODING_SKIPLIST,输出skiplist
每种类型的对象至少使用了两种不同的编码,在不同的条件下redis会对对象进行编码转换,比如如果对象保存的全部都是整数,那么他的编码是int,但是当执行了一些命令之后对象中存储的已经不全部是整数了,那么会把该对象的编码从int变为raw,其它类型的对象同理。

  • 1
    点赞
  • 1
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

<p> <span style="font-size:16px;">概要介绍</span><span style="font-size:16px;">:历经半个多月的时间,Debug呕心沥血、亲自录制的 “缓存中间件Redis技术入门与典型应用场景实战(SpringBoot2.x)”的新课终于完成了,顾名思义,这是一门关于目前相当流行的分布式缓存中间件Redis相关技术栈的介绍与实战,目的在于带领各位小伙伴一起学习、攻克Redis,更好地巩固自己的核心竞争力,跳槽涨薪 自然不在话下!</span> </p> <p> <span style="font-size:16px;"><img src="https://img-bss.csdn.net/201911040416386002.png" alt="" /><br /> </span> </p> <p> <span style="font-size:16px;">值得介绍的是,本课程在技术层面涵盖了中间件<span>Redis</span>的相关技术栈,比如数据结构<span>String</span>、<span>List</span>、<span>Set</span>、<span>SortedSet</span>以及<span>Hash</span>等等,除此之外,在设计并实战“抢红包系统”以及实战各种数据结构对应的应用场景期间,也使用了微服务、分布式相关的技术。包括<span>SpringBoot2.x</span>、<span>Mybatis</span>、热部署工具、二倍均值法、多线程并发编程、发送邮件等等。<br /> </span> </p> <p> <span style="font-size:16px;"><img src="https://img-bss.csdn.net/201911040416139857.png" alt="" /><br /> </span> </p> <p> <span style="font-size:16px;"><img src="https://img-bss.csdn.net/201911040512437801.png" alt="" /><br /> </span> </p> <p> <span style="font-size:16px;"><img src="https://img-bss.csdn.net/201911040512574137.png" alt="" /><br /> </span> </p> <p> <span style="font-size:16px;"><img src="https://img-bss.csdn.net/201911040513156621.png" alt="" /><br /> </span> </p> <span></span>
相关推荐
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值