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. Vue二次精度随笔(2)

    1.vue中数组更新是否会引起视图刷新的研究 (1)vue中修改数组可以引起视图刷新的方法 (2)不会引起数组刷新的方法,需要手动进行赋值 (3)有些数组的变化是不能够引起视图的刷新的,一个是修改数组 ...

  2. Ajax--概述

    1.Ajax(Asynchronous JavaScript and XML),允许浏览器与服务器通信而无需刷新当前页面的技术都被叫做Ajax; 2.XMLHttpRequest:该对象是对JavaS ...

  3. Redis详解(二)——AOF

    Redis详解(二)--AOF 前言 RDB 持久化存在一个缺点是一定时间内做一次备份,如果redis意外down掉的话,就会丢失最后一次快照后的所有修改(数据有丢失).对于数据完整性要求很严格的需求 ...

  4. vmware fusion 进入 BIOS

    要进入bios有三种方法:1.>启动的时候按F2即可进入bios进行一些启动盘等选项的操作.但是,启动的时候很难第一时间按F2成功进入bios, 2.>修改vmware 进入bios之前的 ...

  5. Python字符串魔法方法

    isalpha()判断是否权威字母或者汉字 isdecimal()(十进制小数)    isdigit()  判断是否为数字 特殊数字 isdigit()判断更为厉害   也是判断数字  都返回Tru ...

  6. 南邮CG-CTF Web记录

    MYSQL(利用精度,传参为小数) robots.txt中的代码: <?php if($_GET[id]) { mysql_connect(SAE_MYSQL_HOST_M . ':' . SA ...

  7. 关于目标检测的anchor问题

    关于目标检测其实我一直也在想下面的两个论断: Receptive Field Is Natural Anchor Receptive Field Is All You Need 只是一直没有实验.但是 ...

  8. Codestorm:Game with a Boomerang

    题目连接:https://www.hackerrank.com/contests/codestorm/challenges/game-with-a-boomerang 上一篇博客不知怎么复制过来题目, ...

  9. 运行jar包中的main方法

    java -classpath jar包名.jar 包名.类名

  10. java执行操作系统脚本

    http://www.cnblogs.com/bencakes/p/6139477.html 以前只是知道Runtime.getRuntime().exec(command);这种用法,但是有时候命令 ...