Redis底层原理深入学习

news2025/2/24 16:06:59

一、基本类型及底层实现

 1.String

1)使用场景:简单字符串存储、分布式锁、计数器、全局唯一ID

2)数据结构:C语言中String用char[]表示,源码中用SDS封装char[],这是Redis存储的最小单元,一个SDS最大可以存储512M信息。

 Redis对SDS再次封装成RedisObject,核心作用有两个:

①说明是5种类型的哪一种②里面有指针用来指向SDS

Redis对SDS有如下优化:

①SDS修改后大小大于1M,系统会多分配空间来进行空间预分配。

②SDS是惰性释放空间的,你free了空间,系统会把数据记录下来,下次想用可直接使用。不用新申请空间。

2.List

1)使用场景:栈、队列、集合、简单的消息队列

2)数据结构:底层就是一个双端链表,可以根据先进后出和先进先出的操作组成栈和队列。

 3.Hash

1)使用场景:相关数据存储,比如用户的购物车

2)数据结构:Hash的底层主要是采用dict字典的结构,整体呈现层层封装。

 渐进式扩容:dictht有两个是为了在扩容时不影响前端的CRUD,全部转移完成之后将互换使用。扩容之后的数组大小为大于used*2的2的n次方最小值。对对象操作时如果是新增,则直接插入第二个数组。如果是删除、修改、查询,则先查找第一个数组,没有查到再查找第二个数组。

4.Set

1)使用场景:无序集合数据

2)数据结构:Set是Hash的简化版,这里你可以认为是没有Value的Dict。

5.ZSet

1)使用场景:有序集合数据如积分排行榜、延时队列

2)数据结构:ZSet用的是可以和二叉树媲美的跳跃表来实现的。跳表是多层链表的结合体,每一层的数据是有序的,上一层是下一层的子集,层次越高跳跃性越大,每一层都可以看作是下一层的索引,这些索引的意义就是为了加快跳表的查询速度。

 二、高级数据结构及特性

1.Redis GEO

它的核心思想是把地球近似看作一个球体,GEO利用GeoHash将二维的经纬度转换为字符串(字符串相似标记距离相近),来实现位置的划分跟指定区域的查询。

2.HyperLogLog

它是一种概率数据结构,它使用一种概率算法来统计集合的近似基数(一个集合中不同值的个数)。算法的基本原则是伯努利方程+分桶+调和平均数。它在误差允许范围内,做基数统计的时候非常有用。

3.Bitmap

它用一个bit位来映射某个元素的状态(每个比特位只能表示0和1两种状态),优势是大量的节省内存空间。

4.Bloom Filter

它的基本思想是:当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组的K个点(有效降低概率冲突),把它们置为1。当我们检索时,就看这些点是不是都是1,就能知道集合中有没有它了;如果这些点中有一个为0,则这个元素一定不存在。如果这些点都是1,则这个元素很可能存在。

5.发布订阅

发布者向指定的频道发布消息,订阅这个频道的每个客户端都可以收到消息。

三、持久化和事务

1.RDB是Redis中的数据执行周期性的持久化

优点:压缩后的二进制文,适合冷备份和全量复制,数据文件小,数据备份和恢复远快于AOF。

缺点:RDB是周期性快照,在备份时宕机会导致数据完整性和一致性不高。

2.AOF以每条写入命令为日志

优点:因为是只追加模式,所以没有任何磁盘寻址的开销,一秒一次的通过后台子线程操作,数据一致性比较高。

缺点:AOF同步效率高但是运行效率往往低于RDB,恢复慢于RDB。

建议同时配置RDB和AOF,出现问题时可以第一时间进行RDB恢复,然后用AOF补全数据。

3.Redis事务

事务是指一次性,顺序性,排他性的执行一个队列中的一系列命令。

Redis没有隔离级别的概念,批量操作在EXEC之前被放入缓存队列并不会被实际执行。

Redis不保证原子性,单条命令是原子执行的,但事务不保证原子性。

Redis编译型错误事务中所有代码均不执行,运行时异常错误命令导致异常不影响其它命令正常执行。

Redis的watch指令类似于乐观锁,被监视的某些key被其它客户端修改了,事务队列将不会被执行。

四、过期策略和淘汰策略

1.三种过期策略:处理过期数据

定时过期

每个设置过期时间的key都需要创建一个定时器,到期就会立即对key进行删除。这种策略对内存很友好,但会占用大量CPU资源处理过期数据。

惰性过期

只有当访问一个key时,才去判断是否过期,过期则删除。这种策略可以最大化的节省CPU资源,但对内存非常不友好。

定期过期

每隔一定的时间去扫描一定数量的数据的expires字典中一定数量的key,并删除已过期的key。通过调整扫描的时间间隔和每次扫描的限定耗时,使得CPU和内存资源达到最佳的平衡效果。

redis采用惰性删除+定期过期。

2.六种淘汰策略:内存不足需要额外申请时

Redis的内存淘汰策略是指在Redis的内存不足时,怎么处理需要新写入且需要额外申请空间的数据。

volatile-lru:从已设置过期时间的数据集中挑选最近最小使用的数据淘汰。

volatile-ttl:从已设置过期时间的数据集中挑选即将过期的数据淘汰。

volatile-random:从已设置过期时间的数据集中任意选择数据淘汰。

allkeys-lru:从数据集中挑选最近最小使用的数据淘汰。

allkeys-random:从数据集中任意选择数据淘汰。

no-enviction:禁止驱逐,不删除数据的意思。

五、集群高可用

模式优点缺点
单机架构简单,部署方便机器故障、容量瓶颈、QPS瓶颈
主从高可靠性,读写分离故障恢复复杂,主库的写跟存受单机限制
哨兵部署简单,高可用Slave存在资源浪费,不能解决读写分离
集群数据动态存储solt,可扩展高可用客户端动态感知后端操作,批量操作支持查

1.redis主从同步

Redis全量复制一般发生在Slave初始化阶段,这时需要将Master上所有数据复制一份。

Redis增量复制是Slave初始化后正常工作时master发生的写操作同步到slave的过程。

Redis会把指令放在一个环形队列中,指令同步即是主库指令在从库重放的过程。因为内存容量有限,如果备机一直未同步,指令可能被覆盖。

 2.高可用之哨兵模式

Redis-sentinel是一个独立运行的进程,一般sentinel集群最少需要三个节点且为奇数个。Sentinel可以监视任意多个主服务器及主服务器下的多个从服务器,在被监视的主服务器下线时,自动执行故障转移操作。

一个哨兵发现master故障为主观下线,多个哨兵抉择发现达到quorum数时开始进行切换视为客观下线。 

3.Redis Cluster

Gossip协议不要求任何中心节点,所有节点都可以是对等的,任何一个节点无需知道整个网络的状况,只要网络是通的,任何一个节点就可以把消息散播到全网。

 集群部署至少要3台以上的master节点,集群中超过一半master挂掉或者集群中的master没有slave节点,集群将会进入fail状态。

七、常见问题
1.Redis为什么那么快?

1)基于内存实现:相比操作磁盘速率快百倍。

2)高效的数据结构:多种数据结构支持不同的数据类型。

3)丰富而合理的编码:五种类型根据长度和元素个数适用不同的编码格式。

4)合适的线程模型:单线程+IO多路复用避免上下文切换。

5)Redis6.0后引入多线程提速:读写网络的系统耗时远大于Redis的执行耗时,Redis的瓶颈主要在网络的IO消耗上。多线程可以充分利用多核,多线程任务可以分摊Redis同步IO读写负荷。

值得注意的是,Redis6.0默认多线程是关闭的,多线程可以使性能翻倍,但多线程只是处理网络数据的读取和协议解析,执行命令仍然是单线程顺序执行。

2.缓存雪崩是怎么发生的?

Redis中大批量Key在同一时间统一失效导致所有请求都达到MYSQL,而MYSQL扛不住压力而崩溃。

解决方案:①缓存数据过期时间加一个随机数,防止同一时间集体过期。

②如果缓存数据库是分布式部署,将热点数据分布在不同的缓存数据库。

③设置热点数据永不过期。

3.缓存穿透是什么
缓存穿透是指访问缓存和数据库中都没有的数据,可能导致数据库压力过大。

解决办法:①接口增加鉴权校验或参数校验。

②单个IP每秒访问次数超出阈值拉黑或者关小黑屋一段时间。

③从缓存和数据库中取不到的数据,设置key-null过期时间为15秒防止恶意攻击。

④用布隆过滤器特性也可以。

4.缓存击穿呢

集中对某一个热点Key进行访问,Key失效的瞬间,大量请求进入数据库。

解决办法:设置热点数据永不过期。

5.双写如何保证缓存和数据库数据的一致性?

1)先更新数据库再更新缓存,两个线程交替进行数据库和缓存的修改导致出现脏读现象。

2)先删除缓存,再更新数据库,其中一个线程在没有查到缓存时将数据库查询到的旧值写回缓存导致数据不一致的现象。

延时双删:先淘汰缓存;再写数据库;休眠1秒,再次淘汰缓存;

 CaChe Aside Pattern:更新时先把数据保存到数据库,再让缓存失效。

查询时先从缓存中获取,取到后返回,未取到从数据库中查询,成功后放入缓存。

 6.什么是脑裂?

 脑裂是因为网络原因,导致master节点,slave节点和sentinel集群处在不同的网络分区,此时sentinel集群无法感知master节点的存在,所以salve节点将提升为master节点,此时存在两个不同的master节点就像一个大脑分裂成了两个。

集群脑裂问题中,如果客户端还在基于原来的master节点写入数据,那么新的master节点将无法同步这些数据。当网络问题解决后,sentinel集群将原来的master节点降为slave节点,此时再从新的master中同步数据将造成大量的数据丢失。

解决办法:如果连接到master的slave数量小于表示连接到master的最小数量(min-replicas-to-write)且ping的延迟时间大于表示slave连接到master的最大延迟时间,那么master就会拒绝写请求,这样集群脑裂出现后会将原来master的客户端请求拒绝可以减少数据同步之后的数据丢失。

7.redis如何实现分布式锁,它有哪些优缺点?

主要是利用redis单线程执行互斥命令的特性,根据setnx或者exist命令是否返回1来判断是否枷锁成功,然后处理好锁释放的逻辑就可以了。

优点是相比于zookeeper加锁效率高,缺点是无法重入,而且还可能存在死锁问题。

zookeeper实现锁的过程:通过创建临时顺序节点实现锁功能,优点是可重入,缺点是频繁创建节点相较redis性能比较低下。

 Redission解决续期和死锁问题:

Redission加锁和解锁流程大致如下:

 

 RLock是Redission分布式锁最核心的接口,集成了concurrent包的Lock接口和自己的RLockAsync接口。

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

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

相关文章

安全中级3-nginx反向代理负载均衡的webshell

目录 一、负载均衡 1.nginx的负载均衡 2.nginx 支持的几种策略: 二、负载均衡下的webshell连接(负载均衡下的wenbshell环境下载地址) 1.内部网络的结构 2.场景描述 3.利用我们的中国蚁剑连接我们的代理服务器nginx 三、webshell遇到的…

电脑待机或者睡眠后TeamViewer就无法连接了

电脑待机或者睡眠后TeamViewer就无法连接了 设置睡眠状态下不关闭网卡驱动 公司的笔记本,安装了teamviewer,离开时把teamviewer打开,回家后连接时提示伙伴未在机器上运行,此时电脑处于黑屏、待机、睡眠状态 其实电脑睡眠后会关掉网…

创新管理工具:低代码平台在学校管理中的应用实践

随着信息技术的不断发展,学校管理也随之发生了变革。传统的学校管理方式往往是依靠人工操作,存在信息不透明、效率低下等问题,而数字化管理的出现,可以帮助学校提高管理效率、降低管理成本、提升数据统计和分析能力。而低代码技术…

SWAT模型教程

详情点击链接:SWAT模型教程详情点击链接:SWAT模型(建模方法、实例应用、高级进阶) 一:基于网络资源的SWAT模型快速建模​ 二:基于遥感产品的SWAT模型率定与验证​ 三:基于水文响应单元&#xff…

相机光圈和快门

相机光圈和快门 光圈光圈结构光圈值由来光圈范围光圈作用控制画面明暗控制画面景深和锐度 自动光圈 Auto IrisDC-IRIS原理及问题P-IRIS工作原理 快门快门简介快门速度与曝光快门速度与运动安全快门速度高速快门和慢速快门B门和T门 参考文献 光圈 光圈结构 光圈(Ap…

记一次 Android 源码编译刷机过程

0 背景 为了能在开发设备上运行 adb root 命令得到 root 权限,获得更加强大的调试能力、开发体验,方便以后阅读源码时 Debug 跟踪、进行定制化开发,需要编译 Android 源码 userdebug 版本并刷入手机当中。 1 准备 1.1 硬盘 首先 Android 源…

新星计划 Electron+vue2 桌面应用 2 项目编写

练手的项目,需求简单,打算做平面设计社交类的软件。 一、需求 练手用,简单处理,写个简单的记事本,本地保存txt,能导出为其他格式的文件。 获取用户的网卡地址用于数据加密,本地保存加密后的文…

想变身“科技型”企业?掌汇云数字化服务平台为工业升级加分

40万亿元!占GDP比重达到33.2%,这就是国新办公布的2022年数据,中国工业可以说是当之无愧的支柱产业。 中国工业规模大、覆盖面广,企业员工众多,项目遍及海内外。但由于科技欠发达、信息不流通等因素,近些年…

IDEA中 lombok不生效解决方法

目录 前言: springboot启动的时候报错, 说没有lombok编译器 第一步: 检查插件lombok是否存在 第二步: 查看springboot 官方推荐的lombok版本 -> 2.1 第一步 找到这个parent ctrl点进去 -> 2.2 在点红框位置 进去 -> 2.3 ctrlf 搜索一下 lombok.version 复制这个…

[论文评析]mixup: B EYOND E MPIRICAL R ISK M INIMIZATION, ICLR 2018,

mixup: B EYOND E MPIRICAL R ISK M INIMIZATION 介绍MixupMixup的提出动机Mixup与常规数据增广方法的区别References 介绍 采用ERM训练的模型往往存在泛化能力差的情形-可能是在简单的记忆样本, 对于噪声干扰的鲁棒性很差. 这篇论文提出了一种新的数据增广方法-Mixup, 这里主…

【ChatGPT】不会用ChatGPT?这几个镜像网站解决你的烦恼。

个人主页:【😊个人主页】 文章目录 前言ChatGPT介绍WoChatA TalkChatGPT Next WebAI EDUCHATGPTSITES 前言 还在为需要魔法才能与ChatGPT见上一面而叹息吗,今我就为大家汇总了国内能使用ChatGPT的方法。 也就是用国内的镜像网站玩ChatGPT&…

javaWeb 酒店民宿预定信息管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh酒店民宿预定信息管理系统是一套完善的web设计系统(系统采用ssh框架进行设计开发),对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为T…

2023阿里云学生服务器权益,含Clouder认证:云服务器ECS答案

文章目录 阿里云学生权益(服务器使用7个月)1、高校计划续费任务 - 飞天加速计划3.0(2个任务)2、任务1:完成实验《ECS云服务器新手上路》2.2: 续费6个月 3、任务2:Apsara Clouder云计算专项技能认…

【多线程】线程的可见性

目录 一、什么是线程的可见性二、可见性问题示例2.1 代码2.2 截图 三、解决可见性问题3.1 volatile关键字3.2 synchronized关键字 四、用volatile关键字解决可见性问题示例4.1 代码4.2 截图 五、用synchronized关键字解决可见性问题示例5.1 代码5.2 截图 六、可见性与原子性 一…

( 数组) 59. 螺旋矩阵 II ——【Leetcode每日一题】

❓59. 螺旋矩阵 II 难度:中等 给你一个正整数 n ,生成一个包含 1 到 n 2 n^2 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1: 输入:n 3 输出:[[1,2,3],[8,9,4],[7,6,5…

如何动态显示物品提示?

UE5 插件开发指南 前言0 提示信息窗口类前言 为了使物品的排列简洁,各种游戏里的物品信息都是以提示的形式展示出来,而不是整个铺排陈列,只需要玩家鼠标悬停在物品上就自动显示出提示窗口,如下图所示: 这些提示信息在物品定义数据资产中已经定义了,所以这里要做的只是将…

大数据赋能商业地产研策

商业地产是城市经济的重要支柱,也是城市形象的重要名片。在消费者需求日益多元和个性化的背景下,商业地产面临着激烈的市场竞争和运营效率的挑战。如何在复杂多变的市场环境中,做出科学合理的投资决策和运营策略,是商业地产企业的…

Emacs之高效切换窗口(九十二)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

软件测试:功能测试----测试范围和测试策略

一、前言 什么是软件测试?测试能够给我们带来什么?对于企业有什么好处? 软件测试,说的直白就是找bug,而针对的就是我们使用的一些app,网页,系统等等。与之而来的还有硬件测试,这里…

【自动化测试】Java+Selenium自动化测试环境搭建

本主要介绍以Java为基础,搭建Selenium自动化测试环境,并且实现代码编写的过程。 1.Selenium介绍 Selenium 1.0 包含 core、IDE、RC、grid 四部分,selenium 2.0 则是在两位大牛偶遇相互沟通决定把面向对象结构化(OOPP&#xff09…