深入理解Redis

1.数据结构类型

数据结构-SDS-简单动态字符串

Redis构建了一种新字符串结构,称为简单动态字符串(Simple Dynamic String),简称SDS。 Redis未直接使用C语言的字符串,如:char* s = "hello",本质是字符数组: {'h', 'e', 'l', 'l', 'o', '\0'}。因为C语言字符串存在很多问题:a. 获取字符串长度的需要通过运算;  b. 非二进制安全; c. 不可修改;

而使用SDS存在以下优点: a. 获取字符串长度的时间复杂度为O(1);  b. 支持动态扩容;  c. 减少内存分配次数;  d. 二进制安全;

数据结构-IntSet-整数集合

IntSet是Redis中set集合的一种实现方式,基于整数数组来实现,并且具备长度可变、有序等特征。

具备如下特点:   a. Redis会确保Intset中的元素唯一、有序   b. 具备类型升级机制,可以节省内存空间;  c. 底层采用二分查找方式来查询;

HT-哈希表/字典-结构

Dict由三部分组成,分别是:哈希表(DictHashTable)、哈希节点(DictEntry)、字典(Dict),  类似java的HashTable,底层是数组加链表来解决哈希冲突。

ict中的HashTable就是数组结合单向链表的实现,当集合中元素较多时,必然导致哈希冲突增多,链表过长,则查询效率会大大降低。

Dict在每次操作键值对时都会检查负载因子(LoadFactor = used/size) , 满足以下两种情况时会触发哈希表扩容:

  •     哈希表的 LoadFactor >= 1,并且服务器没有执行 BGSAVE 或者 BGREWRITEAOF 等后台进程;   
  •  哈希表的 LoadFactor > 5 ;
  •    扩容大小为第一个大于等于used + 1的2^n;(比如used的是8,则扩容为8+1=9的最近的2的n次方16)

Dict每次删除元素时,也会对负载因子做检查,满足以下情况时会触发哈希表缩容:

  •     当LoadFactor < 0.1 时,会做哈希表收缩:  
  •    收缩大小为第一个大于等于used 的2^n(比如used的是7,则缩容为7的最近的2的n次方8, 但是如果used为8呢?刚好8那岂不是又要扩容?还是说不会出现)

Dict的rehash:

    不管是扩容还是收缩,必定会创建新的哈希表,导致哈希表的size和sizemask变化,而key的查询与sizemask有关。       

 因此必须对哈希表中的每一个key重新计算索引,插入新的哈希表,这个过程称为rehash。

Dict的渐进式rehash:     Dict的rehash并不是一次性完成的。试想一下,如果Dict中包含数百万的entry,要在一次rehash完成,极有可能导致主线程阻塞。         因此Dict的rehash是分多次、渐进式的完成,因此称为渐进式rehash。   

  渐进式rehash过程是这样的:       

 a. 计算新hash表的realeSize,值取决于当前要做的是扩容还是收缩:      

       如果是扩容,则新size为第一个大于等于dict.ht[0].used + 1的2^n           

      如果是收缩,则新size为第一个大于等于dict.ht[0].used的2^n (不得小于4)      

b. 按照新的realeSize申请内存空间,创建dictht,并赋值给dict.ht[1];       

 c. 设置dict.rehashidx = 0,标示开始rehash;         

d. 每次执行新增、查询、修改、删除操作时,都检查一下dict.rehashidx是否大于-1,如果是则将dict.ht[0].table[rehashidx]的entry链 表rehash到dict.ht[1],并且将rehashidx++(注意下一步没有展示)。直至dict.ht[0]的所有数据都rehash到dict.ht[1];  

 e. 将dict.ht[1]赋值给dict.ht[0],给dict.ht[1]初始化为空哈希表,释放原来的dict.ht[0]的内存;

 f. 将rehashidx赋值为-1,代表rehash结束;

   注意:在rehash过程中,新增操作则直接写入ht[1],查询、修改和删除则会在dict.ht[0]和dict.ht[1]依次查找并执行。这样可确保ht[0]的数据只减不增,随rehash最终为空;

渐进式哈希过程

ZipList

ZipList 是一种特殊的“双端链表” ,由一系列特殊编码的连续内存块组成。可以在任意一端进行压入/弹出操作, 并且该操作的时间复杂度为 O(1)。

特征:

a. 列表节点之间不是通过指针连接,而是记录上一节点和本节点长度来寻址,内存占用较低;

 b. 如果列表数据过多,导致链表过长,可能影响查询性能;  

 c. 增或删较大数据时有可能发生连锁更新问题 连锁更新:假设我们有N个连续长度为250~253字节之间的entry,因此entry的previous_entry_length属性用1个字节。如果新增一个entry长度超过253,则后续previous_entry_length需变为5个字节来存储,ZipList这种特殊情况下产生的连续多次空间扩展操作称之为连锁更新(Cascade Update)。新增、删除都可能导致连锁更新的发生。

QuickList

QuickList的特点:是一个节点为ZipList的双端链表;

特点:

a. 节点采用ZipList,解决了传统链表的内存占用问题;

b. 控制了ZipList大小,解决连续内存空间申请效率问题;

c. 中间节点可以压缩,进一步节省了内存;

SkipList

SkipList(跳表)首先是链表,但与传统链表相比有几点差异:

a. 元素按照升序排列存储;

b.  节点可能包含多个指针,指针跨度不同;

特点:

a. 跳跃表是一个双向链表,每个节点都包含score和ele值;    

b. 节点按照score值排序,score值一样则按照ele字典排序;    

c. 每个节点都可以包含多层指针,层数是1到32之间的随机数;        

d. 不同层指针到下一个节点的跨度不同,层级越高,跨度越大;  

e. 增删改查效率与红黑树基本一致,实现却更简单;

2.redis数据结构

String-数据结构

List-数据结构

Redis的List结构类似一个双端链表,是简单的字符串列表,按照插入顺序排序;可以从首、尾操作列表中的元素,添加一个元素到列表的头部(左边)或者尾部(右边);

一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素);

a. 在3.2版本之前,Redis采用ZipList和LinkedList来实现List,当元素数量小于512并且元素大小小于64字节时采用ZipList编码,超过则采用LinkedList编码;

b. 在3.2版本之后,Redis统一采用QuickList来实现List:

Set-数据结构

Set是Redis中的无序集合,满足下列特点:

a. 不保证有序性;  b. 保证元素唯一;  

c. 查询效率极高; 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。添加,删除,查找的复杂度都是 O(1)。

Set是Redis中的无序集合,满足下列特点:

a. 不保证有序性;

 b. 保证元素唯一;  

c. 查询效率极高;

集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。添加,删除,查找的复杂度

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/941665.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端开发 之 12个鼠标交互特效上【附完整源码】

前端开发 之 12个鼠标交互特效上【附完整源码】 文章目录 前端开发 之 12个鼠标交互特效上【附完整源码】一&#xff1a;彩色空心爱心滑动特效1.效果展示2.HTML完整代码 二&#xff1a;彩色实心爱心滑动特效1.效果展示2.HTML完整代码 三&#xff1a;粒子连结特效1.效果展示2.HT…

解析mysqlbinlog

一、前置设置 ps -ef | grep mysql 查看mysql进程对应的安装目录 需设置mysql binlog日志模式为 ROW 二、执行命令 [rootlocalhost bin]# mysqlbinlog --verbose --base64-outputdecode-rows /usr/local/mysql/data/binlog.000069 > 1.sql 查看文件具体内容

理解神经网络

神经网络是一种模拟人类大脑工作方式的计算模型&#xff0c;是深度学习和机器学习领域的基础。 基本原理 神经网络的基本原理是模拟人脑神经系统的功能&#xff0c;通过多个节点&#xff08;也叫神经元&#xff09;的连接和计算&#xff0c;实现非线性模型的组合和输出。每个…

基于Vue.js和SpringBoot的笔记记录分享网站的设计与实现(文末附源码)

博主介绍&#xff1a;✌全网粉丝50W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HLM…

信息安全管理与评估赛题第9套

全国职业院校技能大赛 高等职业教育组 信息安全管理与评估 赛题九 模块一 网络平台搭建与设备安全防护 1 赛项时间 共计180分钟。 2 赛项信息 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段 网络平台搭建与设备安全防护 任务1 网络平台搭建 XX:XX- XX:XX 50 任务2…

怎么在idea中创建springboot项目

最近想系统学习下springboot&#xff0c;尝试一下全栈路线 从零开始&#xff0c;下面将叙述下如何创建项目 环境 首先确保自己环境没问题 jdkMavenidea 创建springboot项目 1.打开idea&#xff0c;选择file->New->Project 2.选择Spring Initializr->设置JDK->…

【计算机视觉基础CV-图像分类】05 - 深入解析ResNet与GoogLeNet:从基础理论到实际应用

引言 在上一篇文章中&#xff0c;我们详细介绍了ResNet与GoogLeNet的网络结构、设计理念及其在图像分类中的应用。本文将继续深入探讨如何在实际项目中应用这些模型&#xff0c;特别是如何保存训练好的模型、加载模型以及使用模型进行新图像的预测。通过这些步骤&#xff0c;读…

【CDN】快速了解CDN是什么?以及工作原理和应用场景

快速了解CDN是什么&#xff1f;以及工作原理和应用场景 一、什么是CDN&#xff1f;CDN相关的术语解释 二、CDN工作原理三、CDN与传统网站的区别四、CDN的作用和意义五、CDN的应用场景 一、什么是CDN&#xff1f; CDN英文全称Content Delivery Network&#xff0c;中文翻译即为内…

leetcode 2295.替换数组中的元素

1.题目要求: 2.题目代码: class Solution { public:vector<int> arrayChange(vector<int>& nums, vector<vector<int>>& operations){map<int,int> element_index;//创建图存入元素和元素对应的下标for(int i 0;i < nums.size()…

clickhouse-题库

1、clickhouse介绍以及架构 clickhouse一个分布式列式存储数据库&#xff0c;主要用于在线分析查询 2、列式存储和行式存储有什么区别&#xff1f; 行式存储&#xff1a; 1&#xff09;、数据是按行存储的 2&#xff09;、没有建立索引的查询消耗很大的IO 3&#xff09;、建…

记录一个SVR学习

1、为什么使用jupter来做数据预测&#xff1f;而不是传统pycharm编辑器 1、Jupyter Notebook 通过anaconda统一管理环境&#xff0c;可以运行python、R、Sql等数据分析常用语言。 2、做到交互式运行&#xff0c;可以逐步运行代码块&#xff0c;实时查看结果&#xff0c;便于调…

【WRF教程第3.2期】预处理系统 WPS详解:以4.5版本为例

预处理系统 WPS 详解&#xff1a;以4.5版本为例 WPS 嵌套域&#xff08;WPS Nested Domains&#xff09;USGS 和 MODIS 土地利用重力波拖拽方案静态数据&#xff08;Gravity Wave Drag Scheme Static Data&#xff09;1. 什么是重力波拖拽方案&#xff08;GWDO&#xff09;静态…

Stealthy Attack on Large Language Model based Recommendation

传统RS依赖id信息进行推荐&#xff0c;攻击&#xff1a;生成虚假用户&#xff0c;这些用户对特定目标物体给于高评价&#xff0c;从而影响模型的训练。 基于llm的RS&#xff1a;llm利用语义理解&#xff0c;将用户兴趣转化为语义向量&#xff0c;通过计算用户兴趣向量与物品向…

Pytorch | 从零构建EfficientNet对CIFAR10进行分类

Pytorch | 从零构建EfficientNet对CIFAR10进行分类 CIFAR10数据集EfficientNet设计理念网络结构性能特点应用领域发展和改进 EfficientNet结构代码详解结构代码代码详解MBConv 类初始化方法前向传播 forward 方法 EfficientNet 类初始化方法前向传播 forward 方法 训练过程和测…

【Linux 网络 (五)】Tcp/Udp协议

Linux 网络 一前言二、Udp协议1&#xff09;、Udp协议特点2&#xff09;、Udp协议格式3&#xff09;、Udp报文封装和解包过程4&#xff09;、UDP的缓冲区 三、TCP协议1&#xff09;、TCP协议特点2&#xff09;、TCP协议格式1、4位首部长度、源端口、目的端口2、16位窗口大小3、…

重温设计模式--命令模式

文章目录 命令模式的详细介绍C 代码示例C代码示例2 命令模式的详细介绍 定义与概念 命令模式属于行为型设计模式&#xff0c;它旨在将一个请求封装成一个对象&#xff0c;从而让你可以用不同的请求对客户端进行参数化&#xff0c;将请求的发送者和接收者解耦&#xff0c;并且能…

Python langchain ReAct 使用范例

0. 介绍 ReAct: Reasoning Acting &#xff0c;ReAct Prompt 由 few-shot task-solving trajectories 组成&#xff0c;包括人工编写的文本推理过程和动作&#xff0c;以及对动作的环境观察。 1. 范例 langchain version 0.3.7 $ pip show langchain Name: langchain Ver…

Java设计模式 —— 【结构型模式】外观模式详解

文章目录 概述结构案例实现优缺点 概述 外观模式又名门面模式&#xff0c;是一种通过为多个复杂的子系统提供一个一致的接口&#xff0c;而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口&#xff0c;外部应用程序不用关心内部子系统的具体的细节&#xff0c;这…

【自用】通信内网部署rzgxxt项目_01,后端pipeDemo部署(使用nssm.exe仿照nohup)

做完这些工作之后&#xff0c;不要忘记打开 Windows Server 的防火墙端口&#xff0c;8181、8081、8080、22、443、1521 做完这些工作之后&#xff0c;不要忘记打开 Windows Server 的防火墙端口&#xff0c;8181、8081、8080、22、443、1521 做完这些工作之后&#xff0c;不要…

Apache RocketMQ 5.1.3安装部署文档

官方文档不好使&#xff0c;可以说是一坨… 关键词&#xff1a;Apache RocketMQ 5.0 JDK 17 废话少说&#xff0c;开整。 1.版本 官网地址&#xff0c;版本如下。 https://rocketmq.apache.org/download2.配置文件 2.1namesrv端口 在ROCKETMQ_HOME/conf下 新增namesrv.pro…