redis 图片2进制保存_Redis的设计于实现(1)

b3ad2342ddbd7fde3c3e0d5d1181c8f8.png

一丶数据结构

简单的动态字符串

Redis的默认字符串类型为SDS。只会使用C字符串作为字面量(比如打印)。

struct 

SDS遵循C字符串以空字符串结尾的惯例,保存空字符串的1字节空间不计入SDS的len属性里面。

优点:字符串的复杂度为O(1);len可直接返回长度。

杜绝缓冲区溢出;SDS的空间分配杜绝了溢出可能。

减少字符串修改带来的内存重分配次数;修改后SDS长度小于1M,分配和len同样大小的未使用空间;修改后大于1M,则每次分配1M空间。

二进制安全,可保存二进制数据;包含空字符串的特殊文本格式,会使C字符串误认为结束,是二进制不安全的。

兼容C字符串函数;可复用C字符串函数库。

链表

C语言没有链表的数据结构。Redis自己构建了链表的实现。

//链表节点

特性:

双端;链表节点带有prev和next指针,获取前后节点的复杂度为O(1)。

无环;表头节点的prev和表尾节点的next都指向null。

带表头指针和表尾指针。

带链表长度计数器。

多态;通过三个函数,可用于保存各种不同类型的值。

字典

C语言没有字典的数据结构。Redis自己构建了字典的实现。、

Redis的数据库就是用字典来实现的,也是哈希建的底层实现。

//哈希表

哈希算法:通过键值对的键计算出hash值与掩码做位与(&)得出索引值。为解决冲突,通过指针构成一个链表,采用头插法。redis使用链地址法解决哈希冲突。

rehash:为ht[1]分配空间,让字典同时持有ht[0]和ht[1]两个哈希表。在字典中维持一个rehashidx,值为0.每次对字典的操作,先在ht[0]上执行然后rehash到ht[1],rehashidx值增加一。随着时间的推移,ht[0]终将全部rehash到ht[1]中。这时将rehashidx置为-1。所有新增加的键值都会保存到ht[1]中

跳跃表

跳跃表是一种有序的数据结构,支持平均O(logN)和最坏O(N)的复杂度;大部分情况下跳跃表的效率和平衡树相媲美。

redis使用跳跃表作为有序集合键的底层实现。

//跳跃表节点

整数集合

整数集合(inset)是集合键的底层实现之一,当一个集合只包含整数值元素,且元素数量不多时,redis就会使用整数集合作为集合键的底层实现。

//整数集合

升级:当将一个新元素添加到整数集合里面,且比集合现有的元素类型都要长时,需要对集合先进行升级,然后再添加元素。(不支持降级,升级后会保持升级后数据类型)

1.根据新元素的类型扩展空间

2.将现有元素类型转换为新类型,并将现有元素放置到新位置上

3.添加新元素到底层数组

压缩列表

压缩列表(ziplist)是列表键和哈希键的底层实现之一。当包含少量列表项,且每个列表项是比较小的字符串时,redis就使用压缩列表来做列表键的底层实现。

压缩列表:

整个压缩列表占用大小起始到结尾节点的字节数节点数量节点1节点2标记结尾
zlbyteszltailzllenentry1entry2zlend

节点:

前一节点的长度(长度小于254字节,值的长度为1字节.长度大于等于254,值的长度为5字节)记录content保存数据的类型和长度
previous_entry_lengthencodingcontent

连锁更新:previous_entry_length字段的长度有1字节和5字节,若连续多个节点的长度为253,若其中一个节点的长度更新为254,则下一节点的previous_entry_length要重1字节变为5字节。引起连锁更新。

对象

redis并没有直接使用上面的数据结构来实现键值的数据库,而是基于这些数据结构创建一个对象系统。包含字符串对象、列表对象、哈希对象、集合对象和有序集合对象这五种类型的对象

//对象

类型:

类型type值TYPE命令输出
字符串REDIS_STRING"string"
列表REDIS_LIST"list"
哈希REDIS_HASH"hash"
集合REDIS_SET"set"
有序集合REDIS_ZSET"zset"

编码:

编码值对应的数据结构
REDIS_ENCODING_INTlong类型的整数
REDIS_ENCODING_ENBSTRembstr编码的简单动态字符串
REDIS_ENCODING_RAW简单动态字符串
REDIS_ENCODING_HT字典
REDIS_ENCODING_LINKEDLIST双向链表
REDIS_ENCODING_ZIPLIST压缩列表
REDIS_ENCODING_INTSET整数集合
REDIS_ENCODING_SKIPLIST跳跃表和字典

不同的组合:

类型编码对象
REDIS_STRINGREDIS_ENCODING_INT整数值字符串
REDIS_STRINGREDIS_ENCODING_EMBSTRembstr编码的简单动态字符串
REDIS_STRINGREDIS_ENCODING_RAW简单动态字符串
REDIS_LISTREDIS_ENCODING_ZIPLIST压缩列表实现的列表对象
REDIS_LISTREDIS_ENCODING_LINKEDLIST双向链表实现的列表对象
REDIS_HSHAREDIS_ENCODING_ZIPLIST压缩列表实现的哈希对象
REDIS_HSHAREDIS_ENCODING_HT字典实现的哈希对象
REDIS_SETREDIS_ENCODING_INTSET整数集合实现的集合对象
REDIS_SETREDIS_ENCODING_HT字典实现的集合对象
REDIS_SETREDIS_ENCODING_ZIPLIST压缩列表实现的有序集合对象
REDIS_SETREDIS_ENCODING_SKIPLIST跳跃表和字典实现的有序集合对象

为什么有序集合要使用跳跃表和字典实现?

字典优点:以O(1)的复杂度查找成员

跳跃表优点:范围型操作需排序,而跳跃表是按排序存储元素的

#可通过下面命令查看编码类型
OBJECT ENCODING key值
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值