Redis

1、Redis的五种数据类型

字符串对象,列表对象,哈希对象,集合对象,有序集合对象(5个对象)

2、Redis键值原理

说明
Redis没有直接使用C语言传统的字符串表实,而是自己构建的一种名为简单动态字符串(Simple dynamic string,SDS)
SDS除了用来保存数据库中的字符串值之外,SDS还被用作缓冲区(buffer)
数据结构

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

3、链表数据结构

作用与特点:
发布与订阅、慢查询、监视器等功能也用到了链表,Redis服务器本身还使用链表来保存多个客户端的状态信息,以及使用链表来构建客户端输出缓冲区;
节点数据结构:

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);
}

Redis的链表实现的特性可以总结如下:
双端:链表节点带有prev和next指针,获取上下节点时间复杂度为O(1);
无环:
带有表头指针和表尾指针:
带链表长度计数器:
多态:链表节点使用void *指针来保存节点值,并且可以通过list结构的dup、free、match三个属性为节点值设置类型特定函数;

4、字典数据结构

说明:
字典,又称为符号表(symbol table)、关联数组(associative array)或映射(map),是一种用于保存键值对(key-value pair)的抽象数据结构。
数据结构:
dictht:

typedef struct dictht {
//哈希表数组
dictEntry **table;
//哈希表大小
unsigned long size;
//哈希表大小掩码,用于计算索引值
//总是等于size-1
unsigned long sizemask;
//该哈希表已有节点的数量
unsigned long used;
} dictht;

dictEntry:

typedef struct dictEntry {
// 键
void *key;
//值
union{
void *val;
uint64_tu64;
int64_ts64;
} v;
// 指向下个哈希表节点,形成链表
struct dictEntry *next;
}

dict:

typedef struct dict{
// 类型特定函数
dictType *type;//(计算哈希值的函数、复制键的函数、复制值的函数、对比键的函数、销毁键的函数、销毁值的函数)
//私有数据
void *privdata;
//哈希表
dictht ht[2];//当有值更新的时候,用于rehash时使用
//rehash 索引
//当rehash不在进行时,值为-1
in trehashidx;
}

5、字典如何计算hash值并解决hash值冲突的

计算公式:
hash = dict->type->hashFucntion(k0);
index = hash&dict->ht[0].sizemask = 6&3 = 0;
(dict->ht[0].sizemask为size-1)
hash与数组大小取与
解决键冲突:
与hashMap一样,使用的是拉链法进行解决冲突

6、扩展和收缩哈希表是怎么进行的

1.为字典的ht1哈希表分配空间
如果是扩展操作,则把大小设置成2的n次方幂
如果是收缩操作,一样的
2.将ht[0]复制到ht1,重新计算索引值
3.将ht[0]变成其他htt,释放ht[0],将ht1设置为ht[0],在ht1新建一个空表哈希表,为下一次rehash做准备

哈希表的扩展与收缩条件:
1)服务器目前没有在执行BGSAVE命令或者BGREWRITEEAOF命令,并且哈希表的负载因子大于等于1。
2)服务器目前正在执行BGSAVE命令或者BGREWRITEAOF命令,并且哈希表的负载因子大于等于5。
load_factor = ht[0].used / ht[0].sizee

渐进式refresh
rehash动作并不是一次性,集中式的完成的,而是分多次,渐进式完成的
rehash的时候,trehashidx增加1,当结束时,trehashidx设置为-1
在渐进的过程中,如果在ht[0]中没有找到,就去ht1中去寻找;

7、跳跃表数据结构

说明:
跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。
跳跃表支持平均O(logN)、最坏O(N)复杂度的节点查找,还可以通过顺序性操作来批量处理节点;

数据结构:

跳跃表节点数据结构:

typedef struct zskiplistNode{
//层
struct zskiplistLevel{
//前进指针
struct zskiplistNode *forward;
//跨度
unsigned int span;
} level[];
//后退指针
struct zskiplistNod4e *backward;
//分值
double score;
//成员对象
robj *obj;
}zskiplistNode;
跳跃表数据结构:
typedef struct zskiplist{
//表头节点和表尾节点
struct skiplistNode *header,*tail;
//表中节点的数量
unsigned long length;
//表中成熟最大的节点的层数;
int level;s
}zskiplist;	

跳表示意图:
在这里插入图片描述

8、整数集合

说明:
整数结合(intest)是集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合的元素数量不多时,Redis就会使用整数集合作为集合键的底层实现。
(保存类型为int16_t、int32_t或者int64_t的整数值、并且保证集合中不会出现重复元素)
数据结构:

typedef struct intset{
//编码方式
uin32_t encoding;
//集合包含的元素数量
uint32_t length;
//保存元素的数组
int8_t contents[];
}intset;

优点:要让一个数组可以同时保存int16_t、int32_t、int64_t三种类型的值,最简单的做法就是直接使用int64_t类型的数组作为整数集合的底层实现。不过这样一来,即使添加到整数集合里面的都是int16_t类型或者int32_t类型的值,数组都需要使用int64_t类型的空间去保存它们,从而出现浪费内存的情况。

9、压缩列表数据结构

说明:
压缩列表(ziplist)是列表键和哈希键的底层实现之一。当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表来做列表键的底层实现。
在这里插入图片描述

10、对象数据结构

说明:
Redis并没有直接使用这些数据结构来实现键值对数据库,而是基于这些数据结构创建了一个对象系统,这个系统包含字符串对象、列表对象、哈希对象、集合对象和有序集合对象这五种类型的对象,每种对象都用到了至少一种我们前面所介绍的数据结构。
数据结构:

typeedf struct redisObject{
//类型
unsigned type;
//编码
unsigned encode;
//指向底层数据结构的指针
void *ptr;
unsigned lru:
}

type类型如下:

在这里插入图片描述
encoding类型如下:
在这里插入图片描述
不同类型和编码的对象:

在这里插入图片描述
键的空转时长还有另外一项作用:如果服务器打开了maxmemory选项,并且服务器用于回收内存打的算法为volatile-lru或者allkeys-lru,那么当服务器占用的内存数超过了maxmemory选项所设置的上限值时,空转时长较高的那部分键会优先被服务器释放,从而回收内存(配置文件)。

11、数据结构与对象的重要总结

1、Redis数据库中的每个键值对的键和值都是一个对象。
2、Redis共有字符串、列表、哈希、集合、有序集合五种类型的对象,每种类型的对象至少都有两种或以上的编码方式,不同的编码可以在不同的使用场景上优化对象的使用效率。
3、服务器在执行某些命令之前,会先检查给定值类型能否执行指定的命令,而检查一个键的类型就是检查键的值对象的类型;
4、Redis的对象系统带有引用计数实现的内存实现机制,当一个对象不再被使用时,该对象所占用的内存就会被释放掉。
5、Redis所共享值为0到9999的字符串对象
6、对象会记录自己的最后一次被访问的时间,这个时间可以用于计算对象的空转时间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值