redis核心设计原理

文章目录

  • 一、redis应用场景
  • 二、redis基本特性
    • redis字符串SDS
    • SDS与C字符串的区别
  • K-V
  • redis的DB是如何实现的
  • bitmap
  • 总结


一、redis应用场景

redis核心设计原理_第1张图片

二、redis基本特性

redis核心设计原理_第2张图片

redis字符串SDS

SDS,simple dynamic string

struct sdshdr{
	//记录buf数组中已使用字节的数量
	//等于SDS所保存字符串的长度
	int len;
	//记录buf数组中未使用字节的数量
	int free;
	//字符数组,用于保存字符串
	char buf[];
{

SDS与C字符串的区别

C语言使用长度为N+!的字符数组来表示长度为N的字符串,并且字符数组的最后一个元素总为空字符’/0’。
如果接受字符串包括/0后面的会被丢弃。
SDS是二进制安全的字符串
定义了len属性可以常数复杂度获取字符串长度,杜绝缓冲区溢出,内存预分配机制,减少修改字符串时带来的内存分配次数。扩容的时候会按照(len+addlen)*2的方式分配内存空间,长度加上需要增加的长度再乘以二,分配完len和free的值相等。应用到append,setbit命令下。如果长度加到1M的空间,以后每次分配空间都会增加1M。


3.2版本之后判断字符串长度,分配不同的位数,如果都用32位的会浪费很多空间,2^32 - 1 达到了上亿。
flags占一个字节,8个bit,前面三个bit表示类型,后面的len表示业务数据的长度,如果都为0表示sdshdr5。

K-V

map -> dict
数据库:海量数据的存储、随机访问

redis仅仅使用了
1、数组:O(1)
2、链表:O(N)
完成了海量数据的存储

创建一个大的数组不划算,创建小的hash后取模:arr[4]

hash(key) -> 自然数[大]%4 = [0,arr.size-1]
1、任意相同的输入,一定能得到相同的输出
2、不同的输入,有可能得到相同的输出
redis核心设计原理_第3张图片
产生hash碰撞之后采用链地址法
redis核心设计原理_第4张图片

开放地址法就是把碰撞的塞到下一位,一般不使用,很难维护。

key:string
value:string,hash,set,sorted set,list

redis的DB是如何实现的

server.h 的redisDb
redis核心设计原理_第5张图片
K-V存储在dict里,expire存储过期时间,blocking keys 阻塞队列维护key - client。select 0 ,0就是id。
redis核心设计原理_第6张图片
keycompare比较key一样不一样(equals方法),判断是否产生了hash冲突
redis核心设计原理_第7张图片
redis扩容是成倍的扩容,每个字典都有两个数据结构,为了实现渐进式rehash。
rehash时获取数据,如果产生hash冲突会先从老的里面找,老的里面找到搬到新的里面去。
同步搬,一次搬少量桶。
redis核心设计原理_第8张图片
redis核心设计原理_第9张图片
type用来约束客户端的命令。
redis核心设计原理_第10张图片
size每次都是2的n次方,sizemash为size - 1,用位运算方式求模提升效率。
扩容的时候采用 任意数 &(2^n - 1)
redis核心设计原理_第11张图片

搬数据是一个桶一个桶的搬,如果数据搬完就会把ht[0]只想ht[1],ht[1]指向null,恢复为rehash之前的状态。

缓存行一次读入64个字节
redis核心设计原理_第12张图片
后面连续的空间可以存储数据,提升效率。

bitmap

只有要两种状态都可以用bit:0/1来表示。比如是否登录,2个字节可以表示16个,key可以使用登录日期,value用bit存储
redis核心设计原理_第13张图片
get bit 可以在O(1)的时间复杂度拿到数据。

总结

你可能感兴趣的:(Redis,redis)