Redis底层原理深入学习

这篇具有很好参考价值的文章主要介绍了Redis底层原理深入学习。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、基本类型及底层实现

Redis底层原理深入学习

 1.String

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

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

Redis底层原理深入学习

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

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

Redis对SDS有如下优化:

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

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

2.List

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

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

Redis底层原理深入学习

 3.Hash

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

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

Redis底层原理深入学习

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

4.Set

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

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

5.ZSet

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

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

Redis底层原理深入学习

 二、高级数据结构及特性

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底层原理深入学习

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

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

 2.高可用之哨兵模式

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

Redis底层原理深入学习

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

3.Redis Cluster

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

Redis底层原理深入学习

 集群部署至少要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)先更新数据库再更新缓存,两个线程交替进行数据库和缓存的修改导致出现脏读现象。

Redis底层原理深入学习

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

Redis底层原理深入学习

延时双删:先淘汰缓存;再写数据库;休眠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性能比较低下。
Redis底层原理深入学习

 Redission解决续期和死锁问题:

Redis底层原理深入学习

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

 Redis底层原理深入学习

 RLock是Redission分布式锁最核心的接口,集成了concurrent包的Lock接口和自己的RLockAsync接口。文章来源地址https://www.toymoban.com/news/detail-478027.html

到了这里,关于Redis底层原理深入学习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Redis-带你深入学习数据类型list

    目录 1、list列表 2、list相关命令 2.1、添加相关命令:rpush、lpush、linsert 2.2、查找相关命令:lrange、lindex、llen 2.3、删除相关命令:lpop、rpop、lrem、ltrim 2.4、修改相关命令:lset 2.5、阻塞相关命令:blpop、brpop 3、应用场景 3.1、消息队列  3.2、最新列表         redis中list并非是一

    2024年02月09日
    浏览(41)
  • Redis带你深入学习数据类型set

    目录 1、set 2、set相关命令 2.1、添加元素 sadd 2.2、获取元素 smembers 2.3、判断元素是否存在 sismember 2.4、获取set中元素数量 scard 2.5、删除元素spop、srem 2.6、移动元素smove 2.7、集合中相关命令:sinter、sinterstore、sunion、sunionstore、sdiff、sdiffstore 3、应用场景 set数据类型的特点: s

    2024年02月09日
    浏览(44)
  • 深入学习 redis - Stream、Geospatial、HyperLogLog、Bitmap、Bitfields 类型扩展

    目录 前言 Stream geospatial HyperLogLog Bitmaps Bitfields redis 中最关键的五个数据类型 String、List、Hash、Set、Zset 应用最广泛,同时 redis 也推出了额外的 5 个数据类型,他们分别是针对特殊场景才进行的应用的. Ps:这几种类型的具体使用不用记,记你也记不住,因为不常用,因此我们

    2024年02月15日
    浏览(60)
  • 【Redis】1、学习 Redis 的五大基本数据类型【String、Hash、List、Set、SortedSet】

    🍀 Redis 诞生于2009年,全称是 Re mote D ictionary S erver,远程字典服务器,是一个基于 内存的键值型 NoSQL 数据库 🍀 键值(key-value)型,value 支持多种不同数据结构,功能丰富 🍀 单线程,每个命令具备 原子性 🍀 低延迟,速度快(基于内存、IO 多路复用、良好的编码) 🍀支

    2024年02月11日
    浏览(39)
  • Redis - 数据类型映射底层结构

    从数据类型上体现就是,同一个数据类型,在不同的情况下会使用不同的编码类型,底层所使用的的数据结构也不相同。 字符串对象的编码可以是 int 、 raw 和 embstr 三者之一。 embstr 编码是专门用于保存简短字符串的一种优化编码方式,与 raw 编码会调用两次内存分配函数分

    2023年04月21日
    浏览(36)
  • 深入篇【Linux】学习必备:Shell命令运行原理 + 基本指令

    Linux严格意义上来说是一个操作系统,我们称为\\\"核心\\\",但我们一般用户,是不能直接使用这个\\\"核心\\\"。而是通过\\\"核心\\\"的外壳程序,也就是所谓的Shell来与\\\"核心\\\"沟通。 其实我们所有的指令都要在OS内部运行,但是OS使用的难道太高,我们用户很难直接与OS打交道。 从技术角度

    2024年02月07日
    浏览(84)
  • 「Redis」1. 数据类型的底层实现

    前言:在这篇博文中,我们将简单总结在面试中怎么回答Redis数据类型的底层实现。 因为面试时间就那么点,言简意赅的描述自己会的知识显得尤为重要‼️ 🚀 作者简介:作为某云服务提供商的后端开发人员,我将在这里与大家简要分享一些实用的开发小技巧。在我的职业

    2024年02月10日
    浏览(34)
  • Redis高可用系列——Set类型底层详解

    Redis是一种高性能的键值型数据库,它支持多种数据结构,其中一种是set类型。set类型可以存储一个无序的、不重复的字符串集合,类似于Java中的HashSet或Python中的set。set类型的优点是可以对集合进行快速的添加、删除、判断是否存在等操作,以及对多个集合进行交集、并集、

    2024年02月03日
    浏览(41)
  • 11_Redis经典五大类型源码及底层实现

    SDS 动态字符串 双向链表 压缩列表 zpilist 哈希表 hashtable 调表 skiplist 整数集合 intset 快速列表 quicklist 紧凑列表 listpack Github:https://github.com/redis/redis Redis设计与实现 Redis5设计与源码分析 4.1 源码分析思路 怎么看 外面考什么,看什么 分类 4.2 Redis基本的数据结构(骨架) 简单动

    2024年02月11日
    浏览(35)
  • Redis进阶底层原理-Cluster集群底层

    Redis底层原理篇

    2024年02月16日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包