您好,欢迎来到12图资源库!分享精神,快乐你我!我们只是素材的搬运工!!
  • 首 页
  • 当前位置:首页 > 开发 > WEB开发 >
    能够是目前最详细的Redis内存模型及运用解读(4)
    时间:2018-08-09 08:10 来源:网络整理 作者:网络 浏览:收藏 挑错 推荐 打印

    此外,由于SDS中的buf依然运用了C字符串(即以’\0’开头),因此SDS可以运用C字符串库中的部分函数;但是需求留意的是,只要当SDS用来存储文本数据时才可以这样运用,在存储二进制数据时则不行(’\0’不一定是开头)。

    (3)SDS与C字符串的运用

    Redis在存储对象时,一概运用SDS替代C字符串。例如set hello world命令,hello和world都是以SDS的方式存储的。而sadd myset member1 member2 member3命令,不论是键(”myset”),还是集合中的元素(”member1”、 ”member2”和”member3”),都是以SDS的方式存储。除了存储对象,SDS还用于存储各种缓冲区。

    只要在字符串不会改动的状况下,如打印日志时,才会运用C字符串。

    四、Redis的对象类型与外部编码

    前面曾经说过,Redis支持5种对象类型,而每种结构都有至少两种编码;这样做的益处在于:一方面接口与完成别离,当需求添加或改动外部编码时,用户运用不受影响,另一方面可以依据不同的运用场景切换外部编码,提高效率。

    Redis各种对象类型支持的外部编码如下图所示(图中版本是Redis3.0,Redis前面版本中又添加了外部编码,略过不提;本章所引见的外部编码都是基于3.0的):

    能够是目前最详细的Redis内存模型及运用解读


    图片来源:《Redis设计与完成》

    关于Redis外部编码的转换,都契合以下规律:编码转换在Redis写入数据时完成,且转换进程不可逆,只能从小内存编码向大内存编码转换。

    1、字符串

    (1)概略

    字符串是最基础的类型,由于一切的键都是字符串类型,且字符串之外的其他几种复杂类型的元素也是字符串。

    字符串长度不能超过512MB。

    (2)外部编码

    字符串类型的外部编码有3种,它们的运用场景如下:

    int:8个字节的长整型。字符串值是整型时,这个值运用long整型表示。

    embstr:<=39字节的字符串。embstr与raw都运用redisObject和sds保存数据,区别在于,embstr的运用只分配一次内存空间(因此redisObject和sds是延续的),而raw需求分配两次内存空间(辨别为redisObject和sds分配空间)。因此与raw相比,embstr的益处在于创立时少分配一次空间,删除时少释放一次空间,以及对象的一切数据连在一同,寻觅方便。而embstr的坏处也很清楚,假设字符串的长度添加需求重新分配内存时,整个redisObject和sds都需求重新分配空间,因此redis中的embstr完成为只读。

    raw:大于39个字节的字符串

    示例如下图所示:

    能够是目前最详细的Redis内存模型及运用解读

    embstr和raw停止区分的长度,是39;是由于redisObject的长度是16字节,sds的长度是9+字符串长度;因此当字符串长度是39时,embstr的长度正好是16+9+39=64,jemalloc正好可以分配64字节的内存单元。

    (3)编码转换

    当int数据不再是整数,或大小超过了long的范围时,自动转化为raw。

    而关于embstr,由于其完成是只读的,因此在对embstr对象停止修正时,都会先转化为raw再停止修正,因此,只需是修正embstr对象,修正后的对象一定是raw的,无论能否到达了39个字节。示例如下图所示:

    能够是目前最详细的Redis内存模型及运用解读

    2、列表

    (1)概略

    列表(list)用来存储多个有序的字符串,每个字符串称为元素;一个列表可以存储2^32-1个元素。Redis中的列表支持两端插入和弹出,并可以取得指定位置(或范围)的元素,可以充任数组、队列、栈等。

    (2)外部编码

    列表的外部编码可以是紧缩列表(ziplist)或双端链表(linkedlist)。

    双端链表:由一个list结构和多个listNode结构组成;典型结构如下图所示:

    能够是目前最详细的Redis内存模型及运用解读


    图片来源:《Redis设计与完成》

    经过图中可以看出,双端链表同时保存了表头指针和表尾指针,并且每个节点都有指向前和指向后的指针;链表中保存了列表的长度;dup、free和match为节点值设置类型特定函数,所以链表可以用于保存各种不同类型的值。而链表中每个节点指向的是type为字符串的redisObject。

    紧缩列表:紧缩列表是Redis为了浪费内存而开发的,是由一系列特殊编码的延续内存块(而不是像双端链表一样每个节点是指针)组成的顺序型数据结构;详细结构相比照较复杂,略。与双端链表相比,紧缩列表可以节省内存空间,但是停止修正或增删操作时,复杂度较高;因此当节点数量较少时,可以运用紧缩列表;但是节点数量多时,还是运用双端链表划算。

    紧缩列表不只用于完成列表,也用于完成哈希、有序列表;运用十分普遍。

    (3)编码转换

    只要同时满足下面两个条件时,才会运用紧缩列表:

    列表中元素数量小于512个;

    列表中一切字符串对象都不足64字节。

    假设有一个条件不满足,则运用双端列表;且编码只能够由紧缩列表转化为双端链表,反方向则不能够。

    下图展现了列表编码转换的特点:

    能够是目前最详细的Redis内存模型及运用解读

    (责任编辑:admin)