2019独角兽企业重金招聘Python工程师标准>>>

redis的数据库对象有五种,分别是字符串对象(key-value),列表对象(list),哈希对象(hash),集合对象(set),有序集合(sort set)。

这些数据对象来自于底层数据类型的实现,这些数据类型分别为简单动态字符串,链表,字典,跳跃表,整数集合,压缩列表,对象

以下是redisObject和底层数据结构的关系

简单动态字符串(SDS)

redis的键(KEY)由简单动态字符串实现,字符串对象(key-value)也是由简单动态字符串实现的。而简单动态字符串是由C实现的,它的结构如下

struct sdshr{//记录buf中已经使用的字节数量unsigned int len;//记录buf中未使用的字节数量unsigned int free;//字节数组,存储字符串char buf[];
}

在redis3.2版本后,SDS的结构发生了变化,有多种数据结构,根据情况使用

//字符串长度小于32 Byte
struct __attribute__ ((__packed__)) sdshdr5 {unsigned char flags; /* 记录当前字节数组的属性,到底是哪个SDS结构 */char buf[];/* 保存字符串真正的值 */
};
//字符串长度小于256 Byte,大于32 Byte
struct __attribute__ ((__packed__)) sdshdr8 {uint8_t len; /* 记录当前数组的长度 */uint8_t alloc; /* 记录了当前字节数组总共分配的内存大小 */unsigned char flags; /* 记录当前字节数组的属性,到底是哪个SDS结构 */char buf[];/* 保存字符串真正的值 */
};
//字符串长度小于65536 Byte (64KB),大于256 Byte
struct __attribute__ ((__packed__)) sdshdr16 {uint16_t len; /* 记录当前数组的长度 */uint16_t alloc; /* 记录了当前字节数组总共分配的内存大小 */unsigned char flags; /* 记录当前字节数组的属性,到底是哪个SDS结构 */char buf[];/* 保存字符串真正的值 */
};
//字符串长度小于4294967296 Byte (4GB),大于65536 Byte
struct __attribute__ ((__packed__)) sdshdr32 {uint32_t len; /* 记录当前数组的长度 */uint32_t alloc; /* 记录了当前字节数组总共分配的内存大小 */unsigned char flags; /* 记录当前字节数组的属性,到底是哪个SDS结构 */char buf[];/* 保存字符串真正的值 */
};
//字符串长度大于4294967296 Byte (4GB)
struct __attribute__ ((__packed__)) sdshdr64 {uint64_t len; /* 记录当前数组的长度 */uint64_t alloc; /* 记录了当前字节数组总共分配的内存大小 */unsigned char flags; /* 记录当前字节数组的属性,到底是哪个SDS结构 */char buf[];/* 保存字符串真正的值 */
};

链表

链表是redis对象列表(list)的一种实现。当列表中元素数量比较多,或元素中字符串数量比较大时,就会使用链表结构。链表方便顺序查询,同时也方便插入和删除。

链表由listNode和list组成,其结构如下

typedef struct listNode{struct listNode *prev;//前一个节点struct listNode * next;//后一个节点void * value;//节点值
}
typedef struct list{//头节点listNode  * head;//尾节点listNode  * tail;//长度unsigned long len;//复制函数void *(*dup) (void *ptr);//释放函数void (*free) (void *ptr);//对比函数int (*match)(void *ptr, void *key);
}

结构图如下:

字典

字典可以用来保存键值对,字典的结构和java的hashMap结构相似,采用hash算法保存key。字典由字典,哈希表,哈希表节点实现。其结构如下:

/** 哈希表节点*/
typedef struct dictEntry {// 键void *key;// 值,可以是三种形式:指针,8字节字符,8字节整数union {void *val;uint64_t u64;int64_t s64;} v;//指向下个哈希表节点,形成链表(如下hash冲突,会形成链表)struct dictEntry *next;
} 
/** 哈希表*/
typedef struct dictht {// 哈希表数组// 里面存储dictEntrydictEntry **table;// 哈希表大小unsigned long size;// 哈希表大小掩码,用于计算索引值// 总是等于 size - 1,index = hash & sizemask// 这样所有计算得出的hash值都可以对应于table的索引unsigned long sizemask;// 该哈希表已有节点的数量unsigned long used;
}
/** 字典*/
typedef struct dict {// 类型特定函数,type和privdata是为了多态字典所设置的dictType *type;// 私有数据void *privdata;// 哈希表,每个字典包含两个table// ht[0]是平时使用的哈希表,ht[1]是rehash时使用的哈希表dictht ht[2];// rehash 索引标识// 当 rehash 不在进行时,值为 -1int rehashidx;
}

字典结构图如下:

跳跃表

跳跃表是一种有序的数据结构,它通过score进行排序。跳跃表有层级的概念,每个跳跃表节点有多层,每个层级会按顺序指向之后若干节点的对应层级。这是为了便于查询,通过层级查询节点,会比按score顺序依次查询要快很多。节点和链表的结构如下:

typedef struct zskiplistNode{//层struct zskiplistLevel{//前进指针struct zskiplistNode *forward;//跨度unsigned int span;} level[];//后退指针struct zskiplistNode *backward;//分值double score;//成员对象robj *obj;
}
typedef struct zskiplist {//表头节点和表尾节点struct zskiplistNode *header,*tail;//表中节点数量unsigned long length;//表中层数最大的节点的层数int level;
}

结构图如下:

整数集合

当一个集合的元素数量不大,且类型都为整数时,redis就会使用整数集合进行存储。它的结构如下:

typedef struct intset{//编码方式uint32_t enconding;// 集合包含的元素数量uint32_t length;//保存元素的数组    int8_t contents[];
} 

压缩列表

压缩列表是列表对象和哈希对象的实现方式之一。当一个列表的元素数量不多,且值为整数和不长的字符串,这时redis会使用压缩列表。同样如果一个哈希对象的key和value的值数量不多,且为整数和不长的字符串时,redis也会使用压缩列表

参考资料:

https://www.cnblogs.com/jaycekon/p/6227442.html

https://www.cnblogs.com/jaycekon/p/6277653.html

转载于:https://my.oschina.net/u/241670/blog/3058326

redis底层数据结构简述相关推荐

  1. 保存到redis的字符串类型出现斜杆_深入浅出Redis:这次从Redis底层数据结构开始...

    1.概述 相信使用过Redis 的各位同学都很清楚,Redis 是一个基于键值对(key-value)的分布式存储系统,与Memcached类似,却优于Memcached的一个高性能的key-valu ...

  2. redis底层数据结构之跳跃表

    redis底层数据结构之跳跃表 redis 的zset有序连表为啥选择用跳跃表? 我们要思考一问题,首先多问问自己为什么,才容易理解它,ps:这是个人观点.首先我们选择的数据结构和算法原因有以下几种: ...

  3. 02 Redis 底层数据结构

    一.不同数据类型存储结构 Redis底层数据结构一共有 6 种,分别是简单动态字符串.双向链表.压缩列表.哈希表.跳表和整数数组.它们和数据类型的对应关系如下图所示: 1 数组与链表的区别 数组和链表 ...

  4. Redis底层数据结构详解(一)

    Redis底层数据结构 一.简单动态字符串SDS 1. SDS 2. 为什么Redis没用C语言原生字符串? 2.1 C语言中的字符串 2.2 使用SDS的好处 二.链表linkedlist 三.压缩 ...

  5. Redis面试题-Redis底层数据结构

    本文参考 嗨客网 Redis面试题 Redis底层数据结构 Redis 的五大数据类型也称五大数据对象,即分别为 string. list. hash. set 和 zset,但 Redis 并没有直 ...

  6. Redis底层数据结构详解

    Redis底层数据结构详解 我们知道Redis常用的数据结构有五种,String.List.Hash.Set.ZSet,其他的集中数据结构基本上也是用这五种实现的,那么,这五种是Redis提供给你的数 ...

  7. Redis底层数据结构介绍

    文章目录 前言 1. 哈希表 2. 简单动态字符串 使用SDS的好处 对比C字符串 3. 压缩列表 4. 跳表 5. 整数集合.双向链表 Redis数据类型与底层数据结构对照表 前言 一谈到Redis ...

  8. Redis——底层数据结构原理

    摘要 Redis 发展到现在已经有 9 种数据类型了,其中最基础.最常用的数据类型有 5 种,它们分别是:字符串类型.列表类型.哈希表类型.集合类型.有序集合类型,而在这 5 种数据类型中最常用的是字 ...

  9. Redis底层数据结构(图文详解)

    目录 前言 Redis为什么要使用2个对象?两个对象的好处 redisObject对象解析 String 类型 1.int 整数值实现 2.embstr 3.raw List 类型 1.压缩链表:zi ...

最新文章

  1. TensorFlow官方课程开启,机器学习上车吧
  2. JAVA中字符串连接效率的测试(续)
  3. 3.4 滑动窗口的卷积实现-深度学习第四课《卷积神经网络》-Stanford吴恩达教授
  4. java中String值为空字符串与null的判断方法
  5. Android inflate方法与 findViewById 方法区别
  6. 利用OCR文字识别+百度算法搜索,玩转冲顶大会、百万英雄、芝士超人等答题赢奖金游戏
  7. python3.8安装xlwings出错_Python xlwings模块简单使用
  8. 流程图用计算机if怎么写,if语句流程图
  9. Facebook 开源:PyTorchVideo!
  10. 【Flink】flink keyby 在 subtask 中分配不均的研究
  11. Jsp+Ssm+Mysql实现简单的物流快递管理
  12. C# Winform代码片段-大二下学期的垃圾代码
  13. 总结better-scroll插件的使用
  14. html 图片旋转插件,jQuery插件expander实现图片翻转特效
  15. 世界首席WP(文字处理)布局绘制砖家横空出世
  16. C++中static的用法
  17. 绿盟扫漏出现的Web常规漏洞
  18. 人工智能的数学基础------- 矩阵迹与相似矩阵的本质
  19. Gnome桌面的录屏插件easyscreencast
  20. linux显示mem进行排序,linux下top命令显示详解

热门文章

  1. python笔记之while循环
  2. GPT转MBR怎么转?GPT转MBR完整图文教程
  3. python语法错误怎么办_Python中“函数外返回”语法错误的原因?
  4. python读取序列5之后的数据_Python核心编程读笔 5: python的序列
  5. python数据结构题目_《数据结构与算法Python语言描述》习题第二章第三题(python版)...
  6. 控制台应用和空项目有什么区别_农业项目经理和物联网项目经理有什么区别
  7. 泸州计算机专业学院,泸州计算机专业中职推荐
  8. 微软服务器收费吗,了解 Azure 外部服务收费
  9. java打星星_java实现星星图形的输出
  10. java tcp 编程实例_Java实现基于TCP的通讯程序实例解析