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

redis底层数据结构

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

redis底层数据结构

一 、SDS字符串

redis使用SDS作为底层字符串数据结构,实际上也就是字符串 SDS定义:

struct sdshdr{
int len;//  表示字符串长度
int  free;//  表示可用内存空间还有多少字节
char buf[];//   实际存储字符
}

但是和C语言中的字符串有一些区别:
①获取字符串的事件复杂度为O(1)
②不会造成缓冲区溢出,C语言在合并字符串时不一定会预留足够的内存空间,可能造成数据覆盖问题,但是SDS不会,SDS需要修改的时候,首先会检查free大小是否足够,如果不足够会进行空间预分配:如果长度小于1Mb,那么合并以后的剩余空间会等于此时的len,也就是说合并以后free=len,如果长度大于1Mb,那么合并之后的free永远是1Mb。在减少字符串的时候,剩余空间也不会立马被收回,而是在需要的时候,调用相应的API去释放这些空闲空间。
③二进制安全 :C语言字符串以进行结尾,那么有些数据就会有限制,但是SDS不会对其中的数据进行任何限制,过滤等。SDS API都是以处理二进制的方式去处理字符。redis不是用这个数组保存字符,而是保存一系列二进制数据。
④但是实际上SDS字符串的结尾仍然是。这是为了兼容一些C字符串函数
 

二、字典

//字典底层代码

typedef struct dictEntry {
	void* key; // 健
	union {
		void* val;
		uint64_t u64;
		int64_t s64;
	}v;  //值
	struct  dictEntry* next;  //指向下个节点
}dictEntry;

typedef struct dictht {
	dictEntry** table;
	unsigned long size;   //哈希表大小 
	unsigned long sizemask;  //哈希表掩码  总是等于size-1
	unsigned long  used;   //目前已经有的节点数量
}dictht;

typedef struct dictType {
	//各种函数 比如计算哈希值,复制数据,对比数据,销毁数据等
};

typedef struct dict {
	dictType* type;  //类型特定函数
	void* privdata;   //私有数据
	dictht ht[2];   //哈希表
	int rehashidx;  //索引
};

哈希算法:使用哈希函数计算key的哈希值,然后与sizemask进行与运算,得到的结果就是索引值。

redis的哈希表使用链地址法解决冲突。但是由于链表没有尾结点,所以在插入数据的时候,采用头插法。

负载因子:哈希表已经存在的节点数量/哈希表大小
服务器在执行BGSAVE或者BGREWRITEAOF时,负载因子大于5进行扩展
服务器不在执行BGSAVE或者BGREWRITEAOF时,负载因子大于1进行扩展
负载因子小于0.1时,进行收缩。

渐进式rehash:哈希表中有的数据ht大小为2,一般来说ht[0]用来存放数据,但是当需要扩展的时候,ht[1]就有了用处,使用ht[1]对ht[0]进行复制,但是有时候键值对太多,一次性进行复制会对服务器的性能产生很大影响,所以采用渐进式rehash,每次复制一个链表,此时rehashidx下标就表示目前复制到了哪里。rehashidx=0时,表示rehash开始,每次复制完一个链表以后值加一,当值为-1的时候,表示工作已经完成。在复制完一个链表后,ht[0]对应的链表就会销毁。在此期间,进行查找,先找ht[0],如果没有再去ht[1]找。新增数据的话会直接加在ht[1]中。删除呢?更新呢?

​​​​​​​

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

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

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