栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Redis源码:Redis源码怎么查看、Redis源码查看顺序、Redis外部数据结构到Redis内部数据结构查看源码顺序

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Redis源码:Redis源码怎么查看、Redis源码查看顺序、Redis外部数据结构到Redis内部数据结构查看源码顺序

Redis源码:Redis源码怎么查看、Redis源码查看顺序、Redis外部数据结构到Redis内部数据结构查看源码顺序
  • Redis源码怎么查看
  • Redis源码两个核心文件server.h、dict.h
  • server.h文件
    • redisObject定义
    • redisDb定义
  • dict.h文件
    • dict定义:引用dictht
    • dictht定义:Redis定义的hash表,引用dictEntry
    • dictEntry定义:dictEntry(翻译过来就是字典条目),定义key和value
  • sds.h文件:简单动态字符串,Redis自己实现的字符串,所有的key都是SDS结构
      • SDS是什么:简单动态字符串
      • sds.h文件的sdshdr8的源码截取
      • Redis为什么要用SDS来实现字符串?
  • Redis各数据结构命令、源码分析、应用场景

Redis是KV存储机构的,
这种key、 value的存储方式,Redis一般会用hash表来进行存储,Redis的最外层也是使用的hash表,Redis还有一个hash的数据结构,那个叫做内层的hash。那么内层的hash是怎么实现的?

Redis源码怎么查看

可以去官网找你想要的版本:https://redis.io/download/

我用的版本是6.0.16。
首先下载redis压缩包,https://download.redis.io/releases/redis-6.0.16.tar.gz
解压,进入解压后的redis目录下的src文件夹,redis的所有源代码都存放在此。

Redis源码两个核心文件server.h、dict.h

Redis源码两个核心文件server.h、dict.h,这两个也是最基本的文件。

server.h文件 redisObject定义

dictEntry的val可以不同数据结构类型,因此很乱,
所以设计了redisObject统一管理不同类型的val数据结构,
dictEntry的val指向redisObject,
redisObject的*ptr指向对象实际的数据结构

typedef struct redisObject {	
								
    unsigned type:4;			
								
    unsigned encoding:4;		
								
    unsigned lru:LRU_BITS; 	    
							   
								
    int refcount;				
								
    void *ptr;					
} robj;
redisDb定义
typedef struct redisDb {			
							
    dict *dict;                 	
								
								
    dict *expires;              
								
								
    dict *blocking_keys;        
    dict *ready_keys;           
    dict *watched_keys;         
    int id;                     
    long long avg_ttl;          
    unsigned long expires_cursor; 
    list *defrag_later;         
} redisDb;
dict.h文件 dict定义:引用dictht
typedef struct dict {
    dictType *type;			
							
    void *privdata;			
							
    dictht ht[2];			
							
    long rehashidx; 		
							
							
    unsigned long iterators;
							
} dict;
dictht定义:Redis定义的hash表,引用dictEntry
typedef struct dictht {		
							
    dictEntry **table;		
							
    unsigned long size;		
							
    unsigned long sizemask;	
							
    unsigned long used;		
} dictht;
dictEntry定义:dictEntry(翻译过来就是字典条目),定义key和value
typedef struct dictEntry {	
							
    void *key;				
    union {
        void *val;			
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    struct dictEntry *next;	
} dictEntry;
sds.h文件:简单动态字符串,Redis自己实现的字符串,所有的key都是SDS结构

SDS(Simple Dynamic String):简单动态字符串,Redis会根据String类型的value长度,去选择合适的sdshdr数结构来存储这个value。

SDS是什么:简单动态字符串

SDS(Simple Dynamic String):简单动态字符串,Redis会根据String类型的value长度,去选择合适的sdshdr数结构来存储这个value,这样的设计可以节省内存空间。

# 换算:
2^10=1024byte=1kb
2^20=1MB
2^30=1GB
2^40=1TB
2^50=1PB
2^60=1EB

sdshdr5:2^5=32byte(不用)
sdshdr8:2^8=256byte
sdshdr16:2^16=65536byte=64kb
sdshdr32:2^32=4GB
sdshdr64:2^64=16EB

Redis的key是字符类型,即String,最大可以用得到是512M,那么它的value字符类型,也是String,最大也是512M。
sdshdr32,sdshdr64定义的这么大,但你未必能用得到全部,这也是Redis预留的一种思想,给你足够多的空间,未来可能就用的到这么大了。

sds.h文件的sdshdr8的源码截取
struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; 
				 
				 
    uint8_t alloc; 
				   
	
    unsigned char flags; 
						 
						 
    char buf[];			 
};
Redis为什么要用SDS来实现字符串?

C语言里面也是没有字符串的,它有的是字符数组,有以下特点:

  1. 内存空间预先分配
  2. 获取字符长度(即字符数组的长度)需要从头到尾先遍历一遍,时间复杂度O(n)
  3. C语言的字符数组内存分配是固定的,长度变更引起内存重新分配
  4. 用’’判断字符串结束(如果你存的内容恰好包含,也会认为是结束)

所以Redis基于字符数组实现了自己的字符串SDS:简单动态字符串

C字符数组SDS
获取字符长度的复杂度O(N)获取字符长度的复杂度O(1),因为SDS中uint8_t len存储当前字符数组的长度
API是不安全的,可能会造成称缓冲区溢出API是安全的,不会造成称缓冲区溢出,简单动态字符串可以扩容,而且不需要预先分配,因此不会产生内存溢出
修改字符长度N次必然需要执行N次内存重新分配修改字符长度N次最多需要执行N次内存重新分配,SDS里面有一个特殊的设计,叫做空间的预分配和惰性的空间释放,不管是获取内存还是释放内存都不是及时的,所以性能会提升
只能保存文本数据可以保存文本数据或者二进制数据
可以使用所有库中的函数可以使用部分库中的函数
Redis各数据结构命令、源码分析、应用场景

Redis源码-String:Redis String命令、Redis String存储原理、Redis字符串三种编码类型、Redis String SDS源码解析、Redis String应用场景

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1040599.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号