redis底层数据结构简述
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底层数据结构简述相关推荐
- 保存到redis的字符串类型出现斜杆_深入浅出Redis:这次从Redis底层数据结构开始...
1.概述 相信使用过Redis 的各位同学都很清楚,Redis 是一个基于键值对(key-value)的分布式存储系统,与Memcached类似,却优于Memcached的一个高性能的key-valu ...
- redis底层数据结构之跳跃表
redis底层数据结构之跳跃表 redis 的zset有序连表为啥选择用跳跃表? 我们要思考一问题,首先多问问自己为什么,才容易理解它,ps:这是个人观点.首先我们选择的数据结构和算法原因有以下几种: ...
- 02 Redis 底层数据结构
一.不同数据类型存储结构 Redis底层数据结构一共有 6 种,分别是简单动态字符串.双向链表.压缩列表.哈希表.跳表和整数数组.它们和数据类型的对应关系如下图所示: 1 数组与链表的区别 数组和链表 ...
- Redis底层数据结构详解(一)
Redis底层数据结构 一.简单动态字符串SDS 1. SDS 2. 为什么Redis没用C语言原生字符串? 2.1 C语言中的字符串 2.2 使用SDS的好处 二.链表linkedlist 三.压缩 ...
- Redis面试题-Redis底层数据结构
本文参考 嗨客网 Redis面试题 Redis底层数据结构 Redis 的五大数据类型也称五大数据对象,即分别为 string. list. hash. set 和 zset,但 Redis 并没有直 ...
- Redis底层数据结构详解
Redis底层数据结构详解 我们知道Redis常用的数据结构有五种,String.List.Hash.Set.ZSet,其他的集中数据结构基本上也是用这五种实现的,那么,这五种是Redis提供给你的数 ...
- Redis底层数据结构介绍
文章目录 前言 1. 哈希表 2. 简单动态字符串 使用SDS的好处 对比C字符串 3. 压缩列表 4. 跳表 5. 整数集合.双向链表 Redis数据类型与底层数据结构对照表 前言 一谈到Redis ...
- Redis——底层数据结构原理
摘要 Redis 发展到现在已经有 9 种数据类型了,其中最基础.最常用的数据类型有 5 种,它们分别是:字符串类型.列表类型.哈希表类型.集合类型.有序集合类型,而在这 5 种数据类型中最常用的是字 ...
- Redis底层数据结构(图文详解)
目录 前言 Redis为什么要使用2个对象?两个对象的好处 redisObject对象解析 String 类型 1.int 整数值实现 2.embstr 3.raw List 类型 1.压缩链表:zi ...
最新文章
- TensorFlow官方课程开启,机器学习上车吧
- JAVA中字符串连接效率的测试(续)
- 3.4 滑动窗口的卷积实现-深度学习第四课《卷积神经网络》-Stanford吴恩达教授
- java中String值为空字符串与null的判断方法
- Android inflate方法与 findViewById 方法区别
- 利用OCR文字识别+百度算法搜索,玩转冲顶大会、百万英雄、芝士超人等答题赢奖金游戏
- python3.8安装xlwings出错_Python xlwings模块简单使用
- 流程图用计算机if怎么写,if语句流程图
- Facebook 开源:PyTorchVideo!
- 【Flink】flink keyby 在 subtask 中分配不均的研究
- Jsp+Ssm+Mysql实现简单的物流快递管理
- C# Winform代码片段-大二下学期的垃圾代码
- 总结better-scroll插件的使用
- html 图片旋转插件,jQuery插件expander实现图片翻转特效
- 世界首席WP(文字处理)布局绘制砖家横空出世
- C++中static的用法
- 绿盟扫漏出现的Web常规漏洞
- 人工智能的数学基础------- 矩阵迹与相似矩阵的本质
- Gnome桌面的录屏插件easyscreencast
- linux显示mem进行排序,linux下top命令显示详解
热门文章
- python笔记之while循环
- GPT转MBR怎么转?GPT转MBR完整图文教程
- python语法错误怎么办_Python中“函数外返回”语法错误的原因?
- python读取序列5之后的数据_Python核心编程读笔 5: python的序列
- python数据结构题目_《数据结构与算法Python语言描述》习题第二章第三题(python版)...
- 控制台应用和空项目有什么区别_农业项目经理和物联网项目经理有什么区别
- 泸州计算机专业学院,泸州计算机专业中职推荐
- 微软服务器收费吗,了解 Azure 外部服务收费
- java打星星_java实现星星图形的输出
- java tcp 编程实例_Java实现基于TCP的通讯程序实例解析