Redis学习:
1、Redis五大经典数据类型源码及底层数据结构
-
面试题
- Redis数据类型的底层数据结构
- Redis五大经典类型:String、List、Hash、SET、ZSET
- GEO底层使用的是ZSET,以经纬度对key进行打分,Bitmap底层使用的是string来存放bit数组
-
Redis源码
- Redis是基于C语言进行开发
- 在/src下的.c文件就是redis的源码实现,.h文件是一些定义(接口)
- 或者去github看redis源码
-
Redis源码核心
- Redis基本数据结构
- 只看一些基本数据结构,五大经典数据类型都是基于基本数据结构来实现
- Redis数据库实现
- 数据库底层实现 db.c
- 数据库持久化 rdb.c aof.c
- Redis服务端和客户端实现
- 其他功能源码
- 考什么就看什么,对文件进行分类
- Redis基本数据结构
-
Redis是字典数据库存放KV键值对
-
说明
- Redis既是KV键值对(dict.c)又是内存数据库(db.c)
- db.c启动数据库,然后dict.c形成字典,然后在字典中存放KV键值对,每个value都抽象为object.c对象
- dict.c形成字典,字典就是KV键值对,先生成db数据库,然后生成字典存放KV键值对
- 每个key都是string类型,每个value都被抽象为 redis-object 类型
-
如何使用KV键值对在字典dict.c存储数据
- 先使用db.c生成数据库,然后使用dict.c生成字典,在字典中保存KV键值对,所有的key都是String类型,value都被抽象为object类型
- redis所有的key都是string类型,所有的value都是redis-object类型,其中object被具体实现为string、list、hash、set、zset等
-
十大类型:大多都是基于五大经典数据类型实现
-
五大经典类型:String、List、Hash、Set、Zset
-
五大新类型:GEO(ZSET)、HyperLogLog(STRING)、Bitmap(STRING)、Bitfield(STRING)、Stream,底层大多也是使用五大经典数据类型实现
-
-
上帝视角启动redis服务器
- redis-server启动后先根据db.c创建数据库,再根据dict.c在数据库中创建字典,在字典中以dictHash的形式存放KV键值对,内部有一个keys表,每个key均指向一个object抽象类型的value,并具体实现不同的数据类型
- redis-server启动后先根据db.c创建数据库,再根据dict.c在数据库中创建字典,在字典中以dictHash的形式存放KV键值对,内部有一个keys表,每个key均指向一个object抽象类型的value,并具体实现不同的数据类型
-
redisObject抽象结构体
- KV键值对从dictEntry -> redisObject
- Redis使用字典来存放KV键值对,每一个KV键值对都对应一个dictEntry,每个dictEntry中都有一个key和value指针,分别指向redisObject对象,暴露给用户的是Hash\string\list等数据类型,但底层是SDS、压缩列表和哈希表等具体实现
- KV键值对底层是dictEtry,但暴露给用户是redisObject
- Redis每个KV键值对(对象)都有一个dictEntry(类似HashMap的Entry),存放一个key和一个value,每一个key和value都指向一个redisObject
- redis中每个key的value都是一个object结构体
- 将KV键值对的value抽象为Object结构体对象,不同数据类型分别具体实现
- redis是字典数据库,字典中存放KV键值对,每个key都是字符串,其对应的value都是redsiObject结构体对象
- C语言struct结构体
- struct type_name {属性定义} object_name(可选定义变量);
- typedef关键字定义结构体,此时定义变量时不需要加struct关键字 ![[Pasted image 20241102205231.png]]
- KV键值读取流程
- Redsi底层使用字典dict存放KV键值对,每个KV键值对都有一个dictEntry来存放key和value,每个key和value都指向一个redisObject对象并暴露给用户表示具体的数据类型,而每个redisObject对象内部都有一个指针指向具体类型的实现,即实现数据类型的数据结构
- 每个KV键值对都对应一个dictEntry存放key和value,其中每个key和value都指向一个redisObject对象,**在redisObject对象中通过type表明数据类型,并通过指针指向具体实现的数据结构
- KV键值对从dictEntry -> redisObject
-
Redis存放KV键值对具体实现
- 当redis-server启动时会先根据db.c创建一个数据库,然后在数据库中根据dict.c创建一个字典,并创建hashtable,然后每添加一个KV键值对,就在dicthashtable中创建一个dictEntry来存放当前KV键值对的key和value,且每个key和value均指向一个redisObject对象,在redisObject对象中标明当前数据类型type,并指向具体的实现结构
-
-
五大经典数据类型底层源码以及底层数据结构
1. redis数据类型与底层数据结构总纲
1. redis底层使用dictEntry保存KV键值对,内部有一个key和一个value,每个key和value都指向一个redsiObject,并在redisObject中通过type指明数据类型,然后通过ptr指向具体实现的数据结构
2. 总体数据结构大纲:SDS动态字符串、双向链表、压缩列表ziplist(7之后就不再使用,为了兼容性继续保留)、哈希表hashlist、跳表skiplist、整数集合intset、快速列表quicklist、紧凑列表listpack
3. Redis7之后就不在使用zipList压缩列表,而是引入了listpack紧凑列表,此时String(SDS动态字符串)、SET(哈希表+整数数组)、ZSET(跳表+紧凑列表)、Hash(哈希表+紧凑列表)、List(快表)2. 从 set hello world 开始 1. 当redis-server启动时,会加载server.h,在期内定义了很多常亮和方法,然后调用 db.c 创建redis内部的数据库,然调用dict.c创建字典,并在字典中创建hashtable来存放KV键值对,每个键值对都有一个dictEntry存放到ht中,其内存放了KV键值对的key和value,且**key是string类型的,指向一个SDS对象**(**Redis没有使用C语言的字符数组,而是自定义SDS存放字符串**),**value指向一个redisObject对象**,**在redisObject对象中通过type指明该对象的数据类型,用encoding指明数据结构,然后通过 ptr指针指向该数据类型的具体实现数据结构**![[Pasted image 20241103095904.png]] 2. 每一个KV键值对的dictEntry中均存放着一个key和一个value,**其中key是string类型的,指向一个SDS对象(Redis没有使用C语言的字符数组存放字符串,而是自定义了SDS)**,而**value均指向redisObject对象**,**用type表明value的数据类型**,**用encoding表明该类型底层数据结构**,**用ptr指向具体实现的数据结构** 3. key是string类型,指向一个SDS对象,每个KV键值对都有一个dictEntry,当根据key获得value时,**先判断key是不是指定的key**,**如果是则返回该dictEntry中的value所指向的RedisObject对象**,**当key匹配时,返回value所指向的RedisObject对象** 3. **RedisObject对象**的结构 1. **encoding表示底层存储的编码类型,同一个数据类型的底层编码可能不同** 2. 每个KV键值对的value都是一个redisObject对象,**用type表明具体的数据类型**,**用encoding表明具体的数据结构**,然后**用ptr指向具体数据结构实现**