【Redis】Redis常见面试题(3)
文章目录
- 【Redis】Redis常见面试题(3)
- 1. 特性&应用场景
- 1.1 Redis能实现什么功能
- 1.2 Redis支持分布式的原理
- 1.3 为什么Redis这么快
- 1.4 Redis实现分布式锁
- 1.5 Redis作为缓存
- 2. 数据类型
- 2.1 Redis常用的数据类型有哪些
- 2.2 有序列表的底层是如何实现的
- 2.3 什么是跳跃表
- 2.4 说一下跳跃表的查询流程
- 2.5 跳跃表的随机层数
- 2.6 跳跃表添加节点的流程
- 3. 持久化
- 3.1 Redis怎么保证数据不丢失
- 3.2 RDB和AOF有什么区别
- 3.2.1 AOF 持久化
- 3.2.2 RDB 持久化
- 3.2.3 AOF 持久化策略有哪些
- 4. 数据淘汰
- 4.1 Redis键值过期之后会直接被删除吗
- 4.2 Redis如何淘汰过期键值
- 4.2.1 过期删淘汰策略
- 4.2.2 定期删除得执行流程
- 4.3 Redis如何解决内存不够用问题
- 4.3.1 Redis内存用完会怎么样
- 4.3.1 内存淘汰策略
- 4.3.2 LRU和LFU有什么区别
- 4.4 过期淘汰策略和内存淘汰策略有何不同
- 5. 事务
- 5.1 Redis的事务的使用
- 5.2 Redis和MySQL事务地最大区别是啥
- 6. 多机部署
- 6.1 Redis多机部署有几种方式
- 6.2 主从、哨兵、集群模式有什么区别
本章重点结构:
Redis本质上就是一个数据库,MySQL是关系型数据库,而Redis是文档型数据库,或者说是非关系型数据库
而它们之间没有必要过多比较,因为它们分别适合不同的场景,在不同的场景下它们都有得天独厚的优势
Redis的常见使用场景有以下几个:
就以会话存储为例,原本我们用的是应用程序的Session存储
假设我们的分布式环境,对于一些请求:
本地内存:
远程Redis:
最主要的原因,数据存取发生在内存中,内存IO的速度非常快
**单线程模型:**Redis使用单线程模型来处理客户端请求。可能你会觉得没有多线程并发处理请求,怎么会快呢?
对比:
Spring MVC框架帮助我们接受多个并发的请求,框架帮我们实现多线程处理这些请求(执行接口方法)
Redis接受多个并发的请求,内部还是以单线程模式进行
Redis数据结构的选取非常合适,采用全局的链式哈希表进行存储每一个key-value,同时,Redis对于哈希扩容的处理也很高效,查询时间非常快,是趋近于O(1)的,并且当哈希桶使用个数比较多时,会进行哈希表的扩容,避免时间复杂度的增高
非阻塞I/O :Redis使用了非阻塞 I/O模型,这意味着当进行磁盘读写或者网络通信的时候,Redis并不是等待数据返回,而是继续处理其他请求。这样可以充分利用CPU的时间,提高整体的吞吐量
网络资料
后来一些功能用到了点cpp~
博文链接:【Redis】Redis实现分布式锁_s:103的博客-CSDN博客
博文链接:【Redis】Redis作为缓存_s:103的博客-CSDN博客
Sorted Set也被称为ZSet,原因是有序列表的底层数据库实现是zskiplist,所以也被称之为ZSet
具体使用在专门的章节讲解,不在这里讲解
当数据比较少的时候,有序集合是压缩列表 ziplist(字节数组,比较节省空间)实现的
使用压缩列表存储必须满足的两个条件:
如果不能同时满足这了两个条件,有序集合将会使用跳跃表skiplist进行存储!
由多个链表来实现的数据结构
为什么要用跳跃表呢,以及跳跃表为啥跳跃除了和它的一些链表的节点有跳跃性(跳着存)的还有别的原因
例如刚才的那个跳跃表
跳跃的之前,会进行判断,以此决定往哪跳:
所谓跳跃表,就是在普通链表的基础上增加了多层索引链表,这样在查找时就可以通过在上下不同层级的索引链表间跳跃,以达到快速查找的目的,所以跳跃表是可以降低时间复杂度的到 O(log2N),感兴趣的同学可以去试着证明以下~
索引就相当于,你要在本文中找到“跳跃表的查询流程”的讲解,我们通过索引:
跳跃表,因为redis考虑性能,维护一个规律的成本比较大,所以采取一种随机的策略,就是层数的生成以至于影响节点跳跃的跨度,是随机的,不过并不是等概率的随机,而是生成越高层数的概率越低
维护一个规律的成本比较大,就比如没三个节点,取其中一个节点,生成一层索引,那么添加操作的时候,可能会破坏之前的结构,导致每一层都要因为维护这个规律而去更新
比如刚才的跳跃表,我要添加一个节点,6,随机生成了一个层数:5
生成5层链表:
从下到上插入节点:
这里的1节点其实是头节点,头节点实际上不是有效数据,这里只是个便于理解的例子,具体要复杂的多~
虽然Redis的读写都是在内存中,因为这样操作新能最高,但是Redis重启,内存中的数据就会丢失
为了保证数据不丢失,我们需要将内存中的数据存储到磁盘,以便Redis重启时能够从磁盘中恢复原有的数据,而整个过程就叫做Redis持久化
也就是说 Redis使用了“持久化”技术来保证Redis中的数据不丢失
Redis持久化有以下3种实现方式:
快照方式(RDB,Redis DataBase),将某一时刻的内存数据,照相机照下这个时刻,以二进制的形式存储到磁盘
文件追加方式(AOF,Append Only File),记录所有的操作命令(set/del…),并以文本的形式追加到文件中
混合持久化方式,Redis4.0之后新增的方式,结合RDB和AOF的优点
你会发现很多地方的最后一种最优秀的方式,都是综合了之前的几种方式,各取所长而诞生的新的方式
就像鬼灭之刃的日之呼吸十三型,就是前十二型融会贯通:
将Redis的写操作以日志的形式追加到一个文件中,类似于数据库的事务日志。当Redis重启的时候,可以通过回放AOF文件中的写操作来恢复数据
优点:
缺点:
通过快照的方式,将当前Redis内存中的数据以二进制格式保存到硬盘上的一个文件中。快照文件是一个经过压缩的二进制文件,它代表了某一个时间点上的数据库状态
有3种:
这个配置可以在redis.conf,也就是Redis的配置文件中,通过设置appendfsync属性来决定是哪个策略
参考redis.conf的第622 - 624行:
Redis 中的键值过期之后
常见的过期淘汰策略有以下三种:
前两种都比较好理解:
只用惰性删除是不够的,因为Redis是有最大运行内存的,不能积累得太多;一般会用惰性删除 + 定期删除,而定时删除,开销太大了,不采用!
同时,为了保证过期扫描不会循环过度,导致线程卡死得现象,算法还增加了扫描时间的上限,默认不会超过25ms,定期删除的执行流程,如下图所示:
当Redis运行内存被用完的时候,即超过Redis设置的最大内存(参考第537行设置maxmemory,不设置代表当前机器的可用内存空间)之后,Redis触发保护机制-内存淘汰机制来删除符合条件的键值对,以此保障Redis能正常运行
早期版本的Redis有以下六种内存淘汰机制(内存淘汰策略):
在Redis 4.0版本中又新增了两种淘汰机制:
有点像线程池的几个拒绝策略~
侧重点不同
Redis有事务,但是Redis中的事务主要作用是将多个一次性加入到事务队列中,然后通过EXEC命令一次性执行所有命令,这样就可以减少网络往返次数,提高了批量操作的效率
示例:
exec:
discard:
出错默认自动discard取消(回滚):
Redis事务地本质是将一组指令加入到队列最终一次性执行地,
没有提供像MySQL那样地事务隔离性和隔离级别的设置,在事务启动/执行期间,其他客户端的读写操作不受影响!
主从同步:主从同步(主从复制)是 Redis 高可用服务的基石,也是多机运行中最基础的一个。我们把主要存储数据的节点叫做主节点(master),把其他通过复制主节点数据的副本节点叫做从节点slave)。在 Redis 中一个主节点可以拥有多个从节点,一个从节点也可以是其他服务器的主节点
如果“主”宕机了,其下的“从”就群龙无首,必须手动将“从”变成“主”,Redis才能继续运行;
虽然主从模式成本低,但是要死“主”节点崩溃了,只能通过人为的方式干预~
哨兵模式:哨兵模式 Redis Sentinel是 Redis 的一种运行模式,它专注于对 Redis 实例(主节点、从节点)运行状态的监控,并能够在主节点发生故障时通过一系列的机制实现选主及主从切换,实现故障转移,确保整个 Redis 系统的可用性;
“主”节点崩溃后,哨兵自动将一个“从”节点升级成“主”节点
- 一旦多个实例组成了哨兵集群,即使有哨兵实例出现故障挂掉了,其他哨兵还能继续协作完成主从库切换的工作,包括判定主库是不是处于下线状态,选择新主库,以及通知从库和客户端。
哨兵模式下,“主”节点依旧只有一个,写能力没有多少提升,很有限,规模和需求一大,“主”节点的压力就很大,也没有办法提供太多的价值
所以就有了集群模式
集群模式:Redis 3.0 之前使用的是哨兵模式,而集群模式 Redis Cluster 是 Redis 3.0 版本推出的 Redis 集群方案,它将数据分布在不同的服务区上,以此来降低系统对单主节点的依赖,并且可以大大的提高 Redis 服务的读写性能。
相比于主从同步多了一个自动容灾恢复的优点
集群模式可以实现多个集群、多主节点的平行的性能扩展,多个“主”节点可以分担写操作
哨兵模式在主从模式的基础上,多了个哨兵节点监视,主节点宕机后,某个从节点升级成主节点~
但无论是主从还是哨兵模式,它的性能扩展都是有限的,因为主节点只有一个,而集群模式可以实现多个集群、多主节点的平行扩展,多个“主”节点可以分担写操作!
文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭!Redis优化使用就是遇到的那些常见的问题,使用对应的适当的解决方案!
遇到问题灵活变通,一般遇到的问题都是套了层别的衣服问的!