Redis 存储原理与数据模型(三)

目录

存储结构

 存储转换

数据组织

hash 冲突

 负载因子

扩容

 缩容

 渐进式rehash

 Redis 线程模型

单线程命令处理机制

为什么Redis 命令的单线程快

机制

优化

柔性数组

 Redis reactor_io 多线程网络模型


存储结构

  • key-value键值对通过 hash 的方式存储到数组中
  • value 主要的数据结构有string,list,hash,set,zset
  • value 的数据不是单一类型,可以嵌入 key - value 键值对

 

 存储转换

        redis 在进行编码存储的时候,同一类型不同的数据量会导致编码的方式不同

  • 数据量少的时候,以存储效率高为主
  • 数据量多的时候,以运行查询快为主

数据组织

        redis 的 KV 数据组织方式是字典,通过 hashtable 来实现。hashtable 就是通过 hash 运算的方式来决定字符串放到数组的哪一个槽位,数组的大小根据数据量来进行调整,所以就会涉及到扩容和缩容。

  • 字符串经过 hash 函数运算得到 64 位整数
  • 64 位整数%表长size得到余数,即是字符串在数组中的槽位
  • 将数组存入对应的槽位中

hash 冲突

         当存储的数据个数大于数组的长度时,必将发生冲突,就是在一个槽内存了两个或多个数据。

抽屉原理: n+1个苹果放在 n 个抽屉中,苹果最多的那个抽屉至少有 2 个苹果;64位整数远大 于数组的长度,比如数组长度为 4,那么 1、5、9、1+4n 都是映射到1号位数组;所以大概 率会发生冲突;

 负载因子

负载因子 = used / size , used 是数组存储元素的个数,size 是数组的长度;

负载因子越小,冲突越小;

负载因子越大,冲突越大;

redis 的负载因子是 1

扩容

 如果负载因子 > 1,则会发生扩容,扩容的规则是翻倍扩容;

如果正在 fork (在 rdb、aof 复写以及 rdb-aof 混用情况下)时,会阻止扩容,但是此时若负载 因子 > 5,索引效率大大降低, 则马上扩容;

 扩容的时候,会发生rehash,扩容后每个元素可能会有两个位置出现。

 缩容

如果负载因子 < 0.1 ,则会发生缩容,缩容的规则是恰好包含 used 的 2的n次方;

理解如下:假如此时数组存储元素个数为 9,恰好包含该元素的就是 2的4次方,也就是 16;

缩容也会发生rehash,位置的调整与扩容相反。

 

 渐进式rehash

当 hashtable 中的元素过多的时候,不能一次性 rehash 到 ht[1] ,这样会长期占用 redis,其他 命令得不到响应,所以需要使用渐进式 rehash;

rehash步骤:

        将 ht[0] 中的元素重新经过 hash 函数生成 64 位整数,再对ht[1] 长度进行取余,从而映射到 ht[1]。

渐进式 rehash 规则:

        1. 分治的思想,将 rehash 分到之后的每步增删改查的操作当中;

        2. 在定时器中,闲时最大执行一毫秒 rehash ,每次步长 100 个数组槽位。

处于渐进式 rehash 阶段时,是否会发生扩容缩容?不会!

 Redis 线程模型

        Redis采用"单线程处理命令+多线程处理后台任务"的混合模型。核心命令执行保持单线程特性,通过多线程处理网络I/O、持久化等辅助操作。

单线程命令处理机制

前提:单线程不能有耗时操作

1.避免加锁复杂度

  • 多线程会引入并发冲突,需要加锁控制:
  • 加锁粒度难把控,锁得多了性能下降,锁得少了数据错乱
  • 容易出现死锁、竞态等问题
  • 代码复杂度和维护成本上升

2.避免线程切换开销

  • 多线程会发生频繁的 CPU 上下文切换:
  • 线程切换需要保存/恢复寄存器等上下文信息
  • 如果 Redis 每条命令都切换线程,反而会拉低整体性能

3.数据结构无需加锁

  • 单线程访问所有核心数据结构(如字典、跳表等),天然线程安全
  • 操作原子性强,不会出现“半更新”的问题
  • 命令顺序可控,执行逻辑简单可靠
为什么Redis 命令的单线程快
机制
特点说明
内存数据库所有数据存储在内存中,读取/写入速度极快
高效数据结构字典,跳表,压缩列表,整数集合,quicklist,按需切换,空间与效率均衡
数据组织机制优化渐进式 Rehash,按需扩容,避免一次性耗时操作
Reactor 网络模型使用多路复用(epoll/select/poll),IO 高效
单线程无锁设计所有命令串行执行,避免加锁带来的性能损耗和线程切换开销
优化

1.分治

  •    将rehash分布在每次操作中
  •    定时器 + 空闲时间处理机制

2. 耗时阻塞操作在其他线程中处理

操作线程方式
Lazy Free创建后台线程异步删除大 Key
AOF Rewrite在子进程中异步执行
RDB Save在子进程中快照,不阻塞主线程
Redis 6.0 I/O 多线程网络I/O在多线程中完成,提高并发性能

3.对象类型采用不同的数据结构实现

柔性数组

C99 引入的一种结构体末尾的数组字段,用于实现可变长度数组

  • 柔性数组的大小是在 运行时动态决定的
  • 它不占结构体静态大小,而是结构体分配内存时追加在后面的一段连续空间
struct MyStruct {int id;char name[20];int data[];  // 柔性数组成员,必须是结构体的最后一个字段
};

 Redis reactor_io 多线程网络模型

  • IO密集型程序:主要等待外部资源
  • CPU密集型程序:主要占用CPU计算资源

Redis 主线程管理调度 + 执行命令,IO 线程专职网络通信,让系统性能和单线程一致性两者兼得 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

langchain4j中使用milvus向量数据库做RAG增加索引

安装milvus向量数据库 官方网址 https://milvus.io/zh 使用docker安装milvus mkdir -p /data/docker/milvus cd /data/docker/milvus wget https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh#在docker中启动milvus sh standalone_emb…

UE5.3 C++ 房屋管理系统(一)

一.框架思路 1.如何加载。房屋管理&#xff0c;既然管理。就存在动态加载&#xff0c;和静态加载的考虑。如果是静态加载&#xff0c;就是在编辑器情况下放置&#xff0c;但这样方便了摆放&#xff0c;但管理就需要在开始是将所有的房屋找到加到管理者里。你无法决定拖入场景的…

4.1【LLaMA-Factory 实战】医疗领域大模型:从数据到部署的全流程实践

【LLaMA-Factory实战】医疗领域大模型&#xff1a;从数据到部署的全流程实践 一、引言 在医疗AI领域&#xff0c;构建专业的疾病诊断助手需要解决数据稀缺、知识专业性强、安全合规等多重挑战。本文基于LLaMA-Factory框架&#xff0c;详细介绍如何从0到1打造一个垂直领域的医…

解决LangChain4j报错HTTP/1.1 header parser received no bytes

问题描述 当使用langchain4j-open-ai调用自己部署的大模型服务时报错&#xff1a; public static void main(String[] args) {OpenAiChatModel model OpenAiChatModel.builder().apiKey("none").modelName("qwen2.5-instruct").baseUrl("http://19…

阿里云codeup以及本地gitclone+http

cmd命令行乱码问题、解决 chcp 65001 git代码提交 git add . git commit -m init git push origin master

2025.05.07-淘天算法岗-第二题

📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 02. 完美拼图挑战 问题描述 A先生是一位拼图爱好者,他有两种形状的拼图块: a a a

Spring Boot中Redis序列化配置详解

精心整理了最新的面试资料和简历模板&#xff0c;有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 引言 在使用Spring Boot集成Redis时&#xff0c;序列化方式的选择直接影响数据存储的效率和系统兼容性。默认的JDK序列化存在可读性差、存储空间大等问题&am…

紫禁城多语言海外投资理财返利源码带前端uniapp纯工程文件

测试环境&#xff1a;Linux系统CentOS7.6、宝塔、PHP7.2、MySQL5.6&#xff0c;根目录public&#xff0c;伪静态thinkphp&#xff0c;开启ssl证书 语言&#xff1a;中文简体、英文、越南语、马来语、日语、巴西语、印尼语、泰语 前端是uniapp的源码&#xff0c;我已经把nmp给你…

搭建大数据学习的平台

一、基础环境准备 1. 硬件配置 物理机&#xff1a;建议 16GB 内存以上&#xff0c;500GB 硬盘&#xff0c;多核 CPU虚拟机&#xff1a;至少 3 台&#xff08;1 主 2 从&#xff09;&#xff0c;每台 4GB 内存&#xff0c;50GB 硬盘 2. 操作系统 Ubuntu 20.04 LTS 或 CentOS…

Linux 软硬连接详解

目录 一、软链接&#xff08;Symbolic Link&#xff09; ‌定义与特性 ‌实现方法‌使用 ln -s 命令&#xff1a; 二、硬链接&#xff08;Hard Link&#xff09; 1、是什么 2、工作机制 3、实现方式 一、软链接&#xff08;Symbolic Link&#xff09; ‌定义与特性 定义…

每日c/c++题 备战蓝桥杯(洛谷P1115 最大子段和)

洛谷P1115 最大子段和 题解 题目描述 最大子段和是一道经典的动态规划问题。题目要求&#xff1a;给定一个包含n个整数的序列&#xff0c;找出其中和最大的连续子序列&#xff0c;并输出该最大和。若所有数均为负数&#xff0c;则取最大的那个数。 输入格式&#xff1a; 第…

前端取经路——框架修行:React与Vue的双修之路

大家好,我是老十三,一名前端开发工程师。在前端的江湖中,React与Vue如同两大武林门派,各有千秋。今天,我将带你进入这两大框架的奥秘世界,共同探索组件生命周期、状态管理、性能优化等核心难题的解决之道。无论你是哪派弟子,掌握双修之术,才能在前端之路上游刃有余。准…

PyTorch API 1 - 概述、数学运算、nn、实用工具、函数、张量

文章目录 torch张量创建操作索引、切片、连接与变异操作 加速器生成器随机采样原地随机采样准随机采样 序列化并行计算局部禁用梯度计算数学运算常量逐点运算归约操作比较运算频谱操作其他操作BLAS 和 LAPACK 运算遍历操作遍历操作遍历操作遍历操作遍历操作遍历操作遍历操作遍历…

java命令行打包class为jar并运行

1.创建无包名类: 2.添加依赖jackson 3.引用依赖包 4.命令编译class文件 生成命令: javac -d out -classpath lib/jackson-core-2.13.3.jar:lib/jackson-annotations-2.13.3.jar:lib/jackson-databind-2.13.3.jar src/UdpServer.java 编译生成class文件如下 <

ABC 转 STL 全攻略:格式解析、方法实操与问题解决

在 3D 建模与设计领域&#xff0c;不同格式文件间的转换是一项基础且重要的操作。ABC&#xff08;Alembic&#xff09;和 STL&#xff08;Standard Triangle Language&#xff09;是其中常见的两种格式。ABC 格式因其高效存储和传输 3D 数据的特性&#xff0c;常被用于影视特效…

编写一个处理txt的loader插件,适用于wbepack

处理txt的webpack的loader插件 编写一个处理txt的loader插件&#xff0c;适用于wbepack 编写一个处理txt的loader插件&#xff0c;适用于wbepack 实现一个处理txt的插件&#xff0c;给文本每行前后添加**** module.exports function txtLoader(content) {// 确保 Loader 是异…

DeepSeek的100个应用场景

在春节前夕&#xff0c;浙江杭州的AI企业DeepSeek推出了其开源模型DeepSeek-R1&#xff0c;以仅相当于Open AI最新模型1/30的训练成本&#xff0c;在数学、编程等关键领域展现出媲美GPT-o1的出色性能。发布仅数日&#xff0c;DeepSeek-R1便迅速攀升至中美两国苹果应用商店免费榜…

ev_loop_fork函数

libev监视器介绍&#xff1a;libev监视器用法-CSDN博客 libev loop对象介绍&#xff1a;loop对象-CSDN博客 libev ev_loop_fork函数介绍:ev_loop_fork函数-CSDN博客 libev API吐血整理&#xff1a;https://download.csdn.net/download/qq_39466755/90794251?spm1001.2014.3…

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】金融风控分析案例-10.1 风险数据清洗与特征工程

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 PostgreSQL金融风控分析案例&#xff1a;风险数据清洗与特征工程实战一、案例背景&#xff1a;金融风控数据处理需求二、风险数据清洗实战&#xff08;一&#xff09;缺失值…

OpenCV 的 CUDA 模块中用于将一个多通道 GpuMat 图像拆分成多个单通道图像的函数split()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::cuda::split 是 OpenCV CUDA 模块中的一个函数&#xff0c;用于将一个多通道的 GpuMat 图像拆分成多个单通道的 GpuMat 图像。这个函数是 CP…