参考书:《redis设计与实现》

Redis虽然底层是用C语言写的,但是底层的数据结构并不是直接使用C语言的数据结构,而是自己单独封装的数据结构;

Redis的底层数据结构由,简单动态字符串,链表,字典,跳跃表,整数集合等几种数据结构组成;

1.简单动态字符串

1.定义:

简单动态字符串:SDS(simple dynamic string)redis 自己构建的;数据结构如下:

struct sds{
int free;//未使用长度
int len;//字符长度
char buff[];//字符数组
}

结尾的一个字节不算在len的长度里面;

2.SDS和C字符串的差别

   相同点都是n+1的长度,都是以\0结尾;

   不同点:1.获取字符串长度复杂度不同;

       2.杜绝缓存区溢出

         3.减少字符修改造成的内存再分配次数;   3.1空间预分配;3.2惰性空间释放;

         4.二进制安全;

         5.兼容部分C字符串;

2.链表

1.链表和节点的实现

struct listNode{
struct listNode *prev;
struct listNode *next;
void *value;
}
typeof struct list{
listNode *head;//第一个
listNode *tail;//最后一个节点
unsigned int len;//长度
void *(*dup)(void *ptr);//复制节点函数
void (*free)(void *ptr);//节点值释放函数
int (*match)(void *ptr,void *key)//节点比对函数 }list;

特点:双端(链表带有pre和next两个指针);

   无环(表头的pre和表尾的next都是NULL);

     带表头指针和表尾指针;

     求链表长度计数器(len是链表节点的计数器)

   多态(dup,free,match三个属性设置特定类型,可以保存不同类型的值)

3.字典

1.定义及实现

字典:又称符号表,关联数组或映射,是一种用于保存键值对的抽象数据结构;
在字典中,一个字和一个值进行关联,这些键和值就称为键值对; redis的字典使用哈希表作为底层实现,一个哈希表里面可以有多个哈希表节点,而每个哈希表节点就保存了字典中的一个键值对
  • 哈希表

typedef struct dictht{
dictEntry **table;//哈希表数组
unsigined long size;//哈希表数组大小
unsigined long sizemask;//哈希表大小掩码,值总是size-1
unsigined long used;//哈希表数组已有节点的数量
}

哈希表节点

typeof struct dictEntry{
void *key;//键
union{//值
void *val;
uint64_tu64;
int64_ts64;
} v;
struct dictEntry *next;//指向另一个哈希表节点的指针,可以将多个哈希值相同的键值对连接在一次
}

 字典

typedef struct dist{
dictype *type;//类型特定函数
void *privdata;//私有数据
dictht ht[];//哈希表
in trehashidx;//rehash索引//当rehash不在进行时,值为-1
}dict; typedef struc dictType{
unsigned int (*hashFunction)(const void *key);//计算哈希值的函数
void *(*keyDup)(void *privdata,const void *key);//复制键的函数
void *(*valDup)(void *privdata,const void *obj);
int (*keyCompare)(void *privdata,const void *key1,const void *key2);
void (*keyDestructor)(void *privdata,void *key);
void (*valDestructor)(void *privdata,void * obj);
} dictType ;

2.哈希算法

MurmurHash算法来计算键的哈希值。

3.解决键冲突

当两个键或者两个以上键分配到redis同一索引的时候,就称为键冲突;使用链地址法来解决键冲突;

4.rehash重新散列

目的:为了让平衡因子维持再一个合理的范围,k-v不会太多,也不会太少

5.渐进式rehash

分步进行rehash,为字典分配两个哈希表,当对一个哈希表操作时,程序在指定的操作上,会把旧表中的数据带到新的哈希表。到某一点完全实现rehash.

4.跳跃表

  跳跃表 是一种有序数据结构,它可以在每个节点中维持多个只指向其他节点的指针,从而达到快速访问节点的目的。

  使用的场景:在redis中,一个是实现有序集合键;一个是集群节点中用作内部数据结构;

1.跳跃表节点


结构代码:

5.整数集合

  当一个集合质保和整数值元素,并且这个集合的元素数量不多时;

1.整数集合的实现

整数集合是Redis用于保存整数值的集合抽象数据结构;
typedef struct intset{
uint32_t encoding;//决定contents里面保存的数据类型
uint32_t length;//整数集合包含的元素数量
int8_t contents[];
}inset;

2.升级

  当新元素比整数集合中所有元素的类型都要长时,整数集合需要先升级,再将元素保存到集合里面;

  步骤:1.根据新元素,扩展底层类型;2.将所有元素转换成新元素类型,并保证底层顺序不变;3.将新元素添加到底层里面;

  优点:1.提高灵活性,如果是int_32的就存储相关的元素,如果有int_64的就升级;2.节省内存资源;  

3.降级

整数集合不支持降级

6.压缩列表

  是一种节约内存而开发的顺序型数据结构;

  使用场景:当一个列表项,只有少量数据,且数据比较小,小整数或者短字符的情况下;

1.压缩列表的构成

2.压缩列表节点的构成

  • previous_entry_length:记录前一个结点的长度;

  • encoding:记录content属性所保存的数据和长度;

  • content:保存节点的值;

3.连锁更新

每个previous_entry_length属性都记录前一个界定啊的长度:
如果节点小于254,则需要用1字节长的空间保存这个长度值;如果大于或等于254字节,则用5字节长的空间保存这个长度值

Redis基础01-redis的数据结构的更多相关文章

  1. Redis 02: redis基础知识 + 5种数据结构 + 基础操作命令

    Redis基础知识 1).测试redis服务的性能: redis-benchmark 2).查看redis服务是否正常运行: ping 如果正常---pong 3).查看redis服务器的统计信息: ...

  2. Redis基础(一)数据结构与数据类型

    Redis数据结构 Redis一共有六种数据结构,分别是简单动态字符串.链表.字典.跳表.整数集合.压缩列表. 简单动态字符串(SDS) Redis只会使用C字符串作为字面量,在大多数情况下,Redi ...

  3. Redis基础---5个基本数据结构(比较性记忆)

    “ Redis是一个内存数据库,只用硬盘来进行持久化. Mongodb是半内存数据库 Mysql是硬盘数据库 ” 1. Redis启动 安装好了之后.运行redis-3.2.8/src/下的redis ...

  4. Redis 基础:Redis 简介及安装

    Remote Dictionary Server(Redis)是一个由Salvatore Sanfilippo写的key-value存储系统.Redis是一个开源的使用ANSI C语言编写.遵守BSD ...

  5. redis基础及redis特殊场景使用描述

    数据类型 String set list hash zset redis原理 单线程:redis是单线程+io多路复用:检查文件描述的就绪状态 对比memchached:多线程+锁 redis优势 解 ...

  6. Redis 基础:Redis 数据类型

    Redis 数据类型 Redis支持五种数据类型:string(字符串).hash(哈希).list(列表).set(集合)及zset(sorted set:有序集合). String(字符串) st ...

  7. Redis 实战 —— 01. Redis 数据结构简介

    一些数据库和缓存服务器的特性和功能 P4 名称 类型 数据存储选项 查询类型 附加功能 Redis 使用内存存储(in-memory)的非关系数据库 字符串.列表.哈希表.集合.有序集合 每种数据类型 ...

  8. Redis基础—了解Redis是如何做数据持久化的

    之前的文章介绍了Redis的简单数据结构的相关使用和底层原理,这篇文章我们就来聊一下Redis应该如何保证高可用. 数据持久化 我们知道虽然单机的Redis虽然性能十分的出色, 单机能够扛住10w的Q ...

  9. Redis 基础:Redis 事件处理

    Redis 事件处理 Redis服务器是一个事件驱动程序,服务器需要处理以下两类事件: 文件事件(file event):Redis服务器通过套接字与客户端(或其他Redis服务器)进行连接,而文件事 ...

  10. Redis 基础:Redis 配置

    Redis 配置 Redis的配置文件位于Redis安装目录下,文件名为redis.conf.可以通过CONFIG命令查看或设置配置项.其语法为: # Redis CONFIG命令格式如下: > ...

随机推荐

  1. 在树莓派3b or 3a or 4a or 4b上搭建OpenWebRX

    OpenWebRx OpenWebRX 项目提供了搭建WebSDR的解决方案,该项目基于 Python 编写,除了完全开源外,官方还提供了完备的技术文档.您只需要一台电脑或是树莓派,一个SDR设备和网 ...

  2. JSP+SSM+Mysql实现的学生成绩管理系统

    项目简介 项目来源于:https://gitee.com/z77z/StuSystem 本系统是基于JSP+SSM+Mysql实现的学生成绩管理系统.主要实现的功能有教师管理.学生管理.课程管理.学生 ...

  3. 初学python笔记

    一.关于python ① 由荷兰人Guido van Rossum(龟叔)于1989年圣诞节为打发无聊时间所编写的编程语言. ② python的特点:优雅 明确 简单.代码量少,运行速度快. 缺点:运 ...

  4. tensorflow2.0学习笔记第二章第四节

    2.4损失函数损失函数(loss):预测值(y)与已知答案(y_)的差距 nn优化目标:loss最小->-mse -自定义 -ce(cross entropy)均方误差mse:MSE(y_,y) ...

  5. 最新 iOS 框架整体梳理(二)

    在前面一篇中整理出来了一些了,下面的内容是接着上面一篇的接着整理.上篇具体的内容可以点击这里查看:   最新 iOS 框架整体梳理(一) Part - 2          34.CoreTeleph ...

  6. Go语言圣经[中文版]

    近期整理了一篇Go语言圣经[中文版]在线版本,排版比较适合手机以及PC阅读. Go语言圣经[中文版本]

  7. 撒花,推荐一下我怒肝的 GitHub

    缘起 之前一直有很多小伙伴们找我,让我聊一聊如何学习 Java ,我都直接回复了一个思维导图,后来想一想觉得回答不是很认真,我的初衷是想让小伙伴们根据思维导图中的知识点,采取各个击破 的原则,哪里不会 ...

  8. Arduino + RFID 读取 IC 卡 Arduino uno中获得RFID的UID 并通过串口转发RFID卡号

    RFID简介:射频识别即RFID(Radio Frequency IDentification)技术,又称无线射频识别,是一种通信技术,可通过无线电讯号识别特定目标并读写相关数据,而无需识别系统与特定 ...

  9. 使用python求解向量值函数的雅各比(Jacobian)矩阵

    考虑一个向量值函数$R^m \rightarrow R^n$,即$\textbf{y} = f(\textbf{x})$,它的雅各比(Jacobian)矩阵定义如下. 下面记录下一段使用python求 ...

  10. cb21a_c++_string对象的比较

    *cb21a_c++_string对象的比较s.compare(s2)--区分大小的s.compare(pos1,n1,s2)s.compare(pos1,n1,s2,pos2,n2)s.compar ...