Redis有五种数据类型stringlisthashsetzset(字符串、哈希、列表、集合、有序集合)并且自实现了简单动态字符串双端链表字典压缩列表(ziplist)整数集合跳跃表(skiplist)等数据结构。Redis底层使用了多种数据结构来实现各种特性。对于Redis底层实现的了解,可以让我们对Redis工作原理更加清晰。

Redis的五种数据类型

Redis数据结构与内部编码,如下图:

从上图可知Redis每种数据结构可以有多种实现,比如hash可以用hashtable实现也可以用ziplist实现,这样的好处是当有更好的算法实现的时候,像quickList(快速列表)就是比ziplist和linkedList性能更好,那么这时候用更好的算法来替代底层只需要切换具体的实现方式就可以,而不用改动太多的代码,这个有点类似于设计模式里的策略模式,对于用户来说是无感知的。

redis对象(redisObject)

  redis源码内部是有一个redisObject对象,redis的键值都是redisObject对象,即在创建时会生成一个用于键名的redisObject对象和一个用于键值的redisObject对象,它是一个c语言结构体。

  其结构体如下:

typedef struct redisObject {
// 类型
unsigned type:;
// 编码
unsigned encoding:;
// 指向数据的指针
void *ptr; // 记录对象最后一次被程序访问时间,用于计算空转时长(当前时间-lru)
unsigned lru:; /* lru time (relative to server.lruclock) */
// 引用计数,用于内存回收
int refcount;
} robj;

redisObject包含信息:

  1.数据类型(type)

    数据类型包括对外的数据结构类型,包括string,hash,list,set,sorted set。

    2.编码方式(encoding)

    编码方式包括raw,int,ziplist,linkedlist,hashmap,intset等内部实现的算法。redis在底层设计的时候比较灵活,编码算法都是可以替换的,比如list有ziplist,linkedlist两种实现,在redis3.2版本中又添加了性能更好的quickList数据结构。

    3.数据指针(ptr)

    4.虚拟内存(vm)

    5.其他信息

   结构体中定义中的type:4、encoding:4这种定义方式称为位段类型。位段是C语言中允许在一个结构体中以位为单位来指定其成员所占内存长度,能够用较少的位数存储数据,所以使用位段类型的好处就是避免浪费内存。

简单动态字符串(simple dynamic string,SDS)

虽然Redis是用c语言编写的,但是Redis底层很多地方都哟自己的实现。就比如简单动态字符串。Redis中字符串的表示并没有直接使用C字符串来表示,C字符串仅仅作为字符串字面量。它是以Struct的形式构造了一个SDS的抽象类型。当Redis需要一个可以被修改的字符串时,就会使用SDS来表示。在Redis数据库里,包含字符串值的键值对都是由SDS实现的(Redis中所有的键都是由字符串对象实现的即底层是由SDS实现,Redis中所有的值对象中包含的字符串对象底层也是由SDS实现)。

SDS的定义位于sds.h

struct sdshdr {
// buf 中已占用空间的长度
int len;
// buf 中剩余可用空间的长度
int free;
// 数据空间,默认是使用C字符串的空字符结尾的
char buf[];
};

  

【redis】redis底层数据结构原理--简单动态字符串 链表 字典 跳跃表 整数集合 压缩列表等的更多相关文章

  1. redis底层数据结构--简单动态字符串 链表 字典 跳跃表 整数集合 压缩列表

    1.动态字符串 redis中使用c语言的字符床存储字面量,默认字符串存储采用自己构建的简单动态字符串SDS(symple dynamic string) redis包含字符串的键值对都是用SDS实现的 ...

  2. redis 系列3 数据结构之简单动态字符串 SDS

    一.  SDS概述 Redis 没有直接使用C语言传统的字符串表示,而是自己构建了一种名为简单动态字符串(simple dynamic string, SDS)的抽象类型,并将SDS用作Redis的默 ...

  3. [Redis]Redis的设计与实现-链表/字典/跳跃表

    redis的设计与实现:1.假如有一个用户关系模块,要实现一个共同关注功能,计算出两个用户关注了哪些相同的用户,本质上是计算两个用户关注集合的交集,如果使用关系数据库,需要对两个数据表执行join操作 ...

  4. Redis数据结构之简单动态字符串SDS

    Redis的底层数据结构非常多,其中包括SDS.ZipList.SkipList.LinkedList.HashTable.Intset等.如果你对Redis的理解还只停留在get.set的水平的话, ...

  5. Redis核心原理-简单动态字符串SDS

    SDS简介 Redis是C语言编写的,但没有使用c语言的字符串结构,而是自己实现了一套简单动态字符串 simple dynamic string 简称SDS,SDS兼容C语言的字符串类型,原理类似Ja ...

  6. Redis数据结构之简单动态字符串

    Redis没有直接使用C语言传统的字符串表示(以空字符结尾的字符数组), 而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型, 并将SDS用作Redi ...

  7. 跟着大彬读源码 - Redis 7 - 对象编码之简单动态字符串

    Redis 没有直接使用 C 语言传统的字符串表示(以空字符串结尾的字符数组),而是构建了一种名为简单动态字符串(simple dynamic string)的抽象类型,并将 SDS 用作 Redis ...

  8. Redis源码阅读一:简单动态字符串SDS

    源码阅读基于Redis4.0.9 SDS介绍 redis 127.0.0.1:6379> SET dbname redis OK redis 127.0.0.1:6379> GET dbn ...

  9. Redis底层探秘(二):链表和跳跃表

    链表简介 链表提供了高效的节点重排能力,以及顺序性的节点访问方式,并且可以通过增删节点来灵活地跳转链表的长度. 作为一种常用数据结构,链表内置在很多高级的编程语言里面,因为Redis使用C语言并没有内 ...

随机推荐

  1. 使用 MYSQLBINLOG 来恢复数据

    使用 MYSQLBINLOG 来恢复数据 2009-04-05 12:47:05 标签:mysql mysqlbinlog 恢复 数据库 数据 原创作品,允许转载,转载时请务必以超链接形式标明文章 原 ...

  2. Ubuntu基于Apache为自己的网站开启HTTPS

    暂时放这里链接,之后整理 https://www.deanhan.cn/ubuntu-apache-https.html

  3. jmeter里面Dug Sampler 和json提取器的用法

    1.编写用户详情请求 2.查看结果树 一级一级往上查找父集 3.添加json提取器 步骤:点击[用户详情]请求->添加->后置处理器->json提取器 把查看结果树里面的JSON P ...

  4. Redis——从入门到放弃

    redis简介 Redis is an open source (BSD licensed), in-memory data structure store, used as a database, ...

  5. Noip2018普及组初赛试题解题报告

    解题思路: 一.单项选择题 (答案:DDDBBAAAABABBBB) 1.除D外,其余均为输入设备. 2.除D外,其余都等于(617)10 ,D选项为(619)10. 3.1MB=1024KB=102 ...

  6. Concurrent包下用过哪些类?

    1.executor接口,使用executor接口的子接口ExecutorService用来创建线程池2.Lock接口下的ReentrantLock类,实现同步,比如三个线程循环打印ABCABCABC ...

  7. JVM:垃圾回收

    概述 上一篇文章我们已经了解了 Java 的这几块内存区域.对于垃圾回收来说,针对或者关注的是 Java 堆这块区域.因为对于程序计数器.栈.本地方法栈来说,他们随线程而生,随线程而灭,所以这个区域的 ...

  8. Docker commit 命令

    docker commit :从容器创建一个新的镜像. 语法 docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] OPTIONS说明: -a :提 ...

  9. 树莓派 Raspberry 软件源更改 看门狗启用

    看门狗无法在pi1上执行,似乎后更高级的pi上面才可用 1.替换脚本 下面脚本请直接复制到终端执行!! 适用于raspbian-stretch(基于Debian9) sudo -s echo -e & ...

  10. Netty 异步模型

    简介 Netty中的 I/O 操作是异步的, 包括 Bind.Write.Connect 等操作会简单的返回一个ChannelFuture. 调用者不能立刻获得结果, 而是通过Future-Liste ...