• 【Redis设计与实现】第一部分 :Redis数据结构和对象 总结


    简单动态字符串:SDS

    【Redis笔记】简单动态字符串(SDS)_暮色_年华的博客-CSDN博客_sds动态字符串

    链表:linkedlist

    【Redis笔记】数据结构与对象:链表_暮色_年华的博客-CSDN博客_对象链表

    字典:hashtable、map

    【Redis笔记】数据结构和对象:字典_暮色_年华的博客-CSDN博客

    跳跃表:skiplist

    【redis设计与实现】数据结构:跳跃表(skiplist)_暮色_年华的博客-CSDN博客

    整数集合:intset

    【redis设计与实现】数据结构:整数集合(intset)_暮色_年华的博客-CSDN博客

    压缩列表:ziplist

    【Redis笔记】压缩列表(ziplist)_暮色_年华的博客-CSDN博客

    对象:

    使用对象的好处:

    (1)根据对象的类型来判断一个对象是否可以执行给定的指令

    (2)可以针对不同的使用场景为对象设置多种不同的数据结构实现

    对象的类型和编码:

    Redis每个对象都由一个redisObject结构表示

    type:记录对象的类型

    Redis的键总是一个字符串对象。

    encoding:决定对象的数据结构

    好处:通过encoding属性来设定对象使用的数据结构,提升了Redis的灵活性和效率,因为Redis可以根据不同的使用场景来为一个对象设置不同的数据结构,从而优化对象在某一场景的效率。

     ptr指针:指向对象的底层实现的数据结构

    字符串对象:

    三种编码方式:int,raw,embstr

    (1)如果一个字符串对象保存的是整数值,并且这个整数值可以用long类型表示,那么字符串对象会将整数值保存在字符串对象结构的ptr属性中,并将encoding设置为REDIS_ECODING_INT.

    (2)如果字符串对象保存的是一个字符串值,并且这个字符串值的长度大于32字节,那么字符串对象将使用SDS来保存这个字符串值,并将对象的编码设置为REDIS_ENCODING_RAW

    (3)如果字符串对象保存的是一个字符串值,并且这个字符串值的长度小于等于32字节,那么字符串对象使用embstr编码的方式来保存这个字符串值。

    说明:long double类型的浮点数在Redis中也作为字符串值来保存。浮点数<->字符串

    编码转换:

    int->raw:对象保存的不再是整数值

    embstr->raw:由于embstr只读,如果对embstr执行任何的修改命令,程序首先将对象的编码从embstr转换为raw,然后执行修改命令。

    列表对象:

    两种数据结构实现方式:ziplist,linkedlist

    1、使用ziplist实现时,每个压缩列表节点保存了一个列表元素。

    2、使用linkedlist实现时,每个双端链表节点都保存了一个字符串对象,每个字符串对象都保存了一个列表元素。

    字符串对象时Redis5种类型的对象种唯一一种会被其他四种类型对象嵌套的对象

    编码转换:

     

    哈希对象:

    两种实现方式:ziplist,hashtable

    1、使用ziplist实现时,每当有新的键值对加入哈希对象时,程序会先保存了键的节点加到表尾,然后把值的节点加到表尾

    (1)同一个键值对的两个节点总是紧挨在一起

    (2)先添加的键值对在表头,后添加的键值对在表尾。

    2、使用hashtable实现时,键值对使用字典键值对保存。字典中的每个键和值都是一个字符串对象。

    编码转化:

     

    集合对象:

    两种编码方式:intset,hashtable

    1、使用intset时,集合对象的所有元素被保存在intset中。

    2、使用hashtable时,字典的每个键都是一个字符串对象,每个字符串对象包含了一个集合元素,值全部设为null

    编码转换:

     

    有序集合对象:

    两种编码方式:ziplist,skiplist

    1、使用ziplist时,每个集合使用两个紧挨在一起的压缩列表节点来保存,第一个节点保存元素的成员,第二个元素保存元素的分值。

    压缩列表内的集合元素按分值从小到大进行排序,分值较小的元素被放置在靠近表头的方向,分支较大的元素被放置在表尾的方向。

    2、使用skiplist时,使用zset结构实现,包括字典和跳跃表。

    (1)跳跃表按分值从小到大保存了所有元素集合,每个跳跃表节点保存了一个集合元素:object属性保存成员,score保存分值。如果只使用字典,保持有序时间O(logn),空间O(n)

    (2)字典为有序集合创建一个从成员到分值的映射,字典中 的每个键值对都保存了一个集合元素。可以通过O(1)查找给定成员的分值。如果只使用跳跃表,O(logn)

    (3)zset结构同时使用跳跃表和字典来保存集合元素,但是它们通过指针来共享相同的元素的成员和分值。所以同时使用它们不会浪费额外的内存。

    编码转换:

     

    Redis对象的特性:

    类型检查:

    Redis用于操作键的命令可以分为两种:

    可以对任何类型的键执行;只能对特定类型的键执行。

    在执行一个类型特定的命令之前,Redis会检查键的类型,然后再决定是否执行命令。

    命令多态:

    Redis根据值对象的编码方式,选择合适的代码实现命令。

    基于类型的多态:无论输入的键是什么类型,命令都可以正确的执行

    基于编码的多态:一个命令可以同时用于处理多种不同的编码

    内存回收:

    Redis在对象系统中构建了一个引用计数实现内存回收机制,程序可以跟踪对象的引用计数信息,在适当时候自动释放对象并进行内存回收。

     

    对象共享:

    对象的引用计数可以实现对象共享。

    在Redis中,让多个键共享同一个值的对象:

    (1)让键的值指针指向一个现有的对象。

    (2)将共享对象的引用计数加1

    共享对象机制对于节约内存有帮助,保存相同值对象越多,对象共享机制就能节约越多内存。

    (1)Redis会在初始化服务器时,创建0~9999所有整数值的字符串对象作为共享对象。

    (2)Redis只对包含整数值的字符串对象进行共享

     

    对象的空转时长:

     

  • 相关阅读:
    Python2.7 pip安装tensorflow-1.15
    pixel手机升系统
    GMS地下水数值模拟及溶质(包含反应性溶质)运移模拟技术
    探索MySQL错误: 1241 - Operand should contain 1 column(s)问题解决方案
    msf对小米11进行安全渗透
    Hadoop伪分布式搭建教程(小白教程)
    Web 攻击的日志分析:初学者指南
    golang容易导致内存泄漏的几种情况
    【Python知识】谈谈Python的抽象类
    Netty入门-Channel
  • 原文地址:https://blog.csdn.net/m0_52043808/article/details/125577426