【精选】30+Redis面试题整理(2024)附答案

目录


前言

放弃幻想,拒绝大饼,准备战斗!!!

所有内容均为自用整理收集,答案仅供参考,如有不同意见欢迎评论区私信交流。





Redis基础

项目有用到redis吗?你们项目为什么用redis?

根据实际项目来谈,比如用于(分布式)会话管理、(分布式)缓存、轻量级消息队列、计数器、限流、排序、消息代理、分布式锁、以及点赞排行榜等实时业务等。

为什么用:速度快,高性能、高并发、丰富的数据结构支持、分布式可扩展性高。



redis为什么这么快?

  1. 内存:redis的所有数据都在内存中,因此不需要访问磁盘,极大的降低了访问延迟;内存操作(读写)性能高,支持每秒百万级操作。
  2. 单线程:redis以单线程模式运行,避免了多线程上下文切换的开销问题和多线程竞争问题,提高了CPU利用效率。
  3. 高效的数据结构:redis利用了几个高效的底层数据结构来提高数据操作效率。
  4. 非阻塞I/O多路复用机制:Redis使用非阻塞I/O,这种机制使得redis可以处理多个连接而不阻塞其他操作,从而能快速处理请求,实现高并发和高吞吐量。

了解Redis的线程模型吗?

Reactor模型?

Redis基于Reactor模式开发网络事件处理器,redis将此称为文件事件处理器(file event handler),该处理器以单线程模式运行和处理事件。

文件事件处理器分为四个部分:

  1. 套接字
  2. I/O多路复用程序:用来监听多个套接字请求。
  3. 文件事件分派器:将套接字的事件交给不同的事件处理器。
  4. 具体的事件处理器:实现不同的网络通信需求,比如应答客户端连接、接收客户端命令请求、返回执行结果等操作。

一个文件事件实际上就是套接字操作的抽象,当一个套接字准备好执行连接应答(accept)、写入、读取、关闭操作时就会产生一个文件事件。redis服务器通常会产生多个套接字(多个客户端多个连接访问),所以文件事件有可能会并发的出现,这时I/O多路复用程序会将所有事件的套接字放在一个队列里,然后文件事件分派器根据该队列有序、同步的接收套接字,由于文件事件处理是以单线程运行,所有只有在上一个套接字生产的事件执行完毕后,才会执行下一个套接字事件。



Redis优缺点?

优点:高性能、高并发

  1. 高性能:redis将数据存储在内存中,因此读写速度非常快。
  2. 高并发:redis基于Reactor 模式开发的网络事件处理器(文件事件处理器)是单线程模式运行的,所有操作都是原子性的,天然就支持高并发。
  3. 数据结构丰富:redis支持各种抽象数据结构,如字符串,列表,映射,集合,排序集合,HyperLogLogs,位图,流和空间索引。
  4. 支持持久化:redis支持将数据持久化到磁盘,提供可靠的数据保证。
  5. 分布式支持:redis支持主从复制和哨兵机制,可以实现数据备份、读写分离和自动故障转移,提高系统的可用性和可靠性。

缺点(内存消耗、数据一致性问题、阻塞):

  1. 内存消耗较大:由于redis将数据存储在内存中,因此对于大规模数据的存储需求,需要考虑服务器的内存容量和成本。
  2. CPU操作瓶颈:单线程模型可以避免上下文切换,但是也无法利用现代多核处理器的性能,对于CPU密集型的操作或服务器存在CPU密集型服务时可能存在性能瓶颈(一般很少见,redis的瓶颈主要在内存和网络),这种情况下就不适合处理大量并发请求。
  3. 线程阻塞:当单线程执行的命令阻塞时(慢查询、大key操作、网络问题等),将严重影响redis的性能。
  4. 数据一致性:当redis作为缓存使用时,就一定存在缓存和数据库数据不一致的问题。此外redis的主从复制存在一定的延迟。
  5. 无法处理复杂查询:redis不支持复杂查询操作,对于需要进行复杂数据分析和统计的场景不太适用。
  6. 数据容量受限:由于redis将数据存储在内存中,所以数据的容量受到内存大小的限制,无法存储超过内存容量的数据。



redis如何实现持久化?

为什么要持久化?redis是内存数据库,它的数据都存储在内存中,如果不把数据保存到磁盘里,那么服务器进程一旦退出,服务器的数据就丢失了。

通过两种方式:

  1. RDB(Persistence DB):RDB类似快照,它只能持久化某一时刻的服务器数据。RDB持久化后,文件将被保存至同文件夹下的dump.rdb文件中,且以压缩的二进制文件表示,服务器重启都会加载该文件以加载数据。
  2. AOF(Append Only File):AOF可以支持实时的数据持久化。AOF持久化功能通过保存redis服务器所执行的写命令来记录数据库状态,默认存储在appendonly.aof中,AOF文件中存储的都是redis相关命令。



RDB持久化过程?

1. 持久化部分

Redis有俩个命令进行RDB持久化:

  • SAVE:将会阻塞redis进程,此时服务器不能处理任何命令请求,直到RDB文件创建完毕。
  • BGSAVE:派生子进程(创建子进程执行fork函数时服务器也将会阻塞,不过用时会很短),由子进程创建RDB,服务器进程继续

bgsave命令持久化过程如下:

  1. fork:创建子线程
  2. rdbSave:子线程创建rdb文件(save命令相当于是父进程直接执行这个函数)
  3. signal_parent:子线程创建完成后向父进程发送信号

RDB持久化可以手动执行,也可以根据服务器配置选项定期执行,在配置文件中设置save属性,会让服务器每隔一段时间自行执行一次bgsave命令。可以配置多个save选项,任一选项条件满足时都被会执行。

# save <second> <修改次数>
save 900 1
save 300 10
save 60 10000
# bgsave保存出错时,停止继续写入
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
# The filename where to dump the DB
dbfilename dump.rdb

2. 载入数据
服务器启动时启动的,检测到RDB文件就会自动载入RDB中的数据。



AOF持久化过程?AOF持久化会出现阻塞吗?为什么?

1. 持久化部分
AOF持久化功能的实现可以分为命令追加、文件写入和同步。

  1. 命令追加:当服务器完成一个写命令之后,并不会直接将这些命令写入AOF文件,而是以Redis协议格式将被执行的写命令追加到服务器缓冲区(aof_bug)的末尾。
  2. 文件写入与同步:根据设置的数据同步策略(always、everysec、no),当满足同步条件或缓冲区满时,redis会将AOF缓冲区中的数据一次性写入磁盘的AOF文件。

文件写入的配置如下:

# appendfsync always
# appendfsync no
appendfsync everysec

写入类型的区别:

  • always:每次执行写命令都将缓冲区的内容写入AOF文件。效率最慢,也最安全,故障停机只会丢失一个事件循环中的数据命令。
  • everysec:如果上次同步AOF文件时间距离现在已经超过了1秒,就进行文件同步。该同步由一个线程单独负责效率够快,且故障停机也只会丢失一秒钟的命令数据。
  • no:由操作系统决定何时进行AOF文件的同步。一般来说,os可能会等到缓冲区的空间被填满、或者超过了指定时限之后,才真正地将缓冲区的数据写入到磁盘里面。fsync和fdatasync两个同步函数,可以强制让os立即将缓冲区中的数据写入到磁盘里面。总体写入AOF文件的速度最快,但是单次同步时长是三种模式中最长的。

2. 载入数据
AOF文件只包含了重建数据库状态所需的所有命令,因此服务器只需要重新执行一遍AOF文件中保存的写命令即可恢复服务器状态。大致步骤如下:

  • 创建一个不带网络连接的伪客户端,用来模拟客户端发送写命令。
  • 从AOF文件中执行并分析出一条写命令
  • 使用伪客户端执行被读出的写命令。
  • 重复读取和写入,直到AOF文件被处理完毕。

3. AOF持久化会出现阻塞
Redis每次执行写命令都将缓冲区的内容写入AOF文件,此时线程可能会因为持久化操作(磁盘IO)而阻塞。



你知道AOF重写吗?为什么要进行重写?简单说下AOF重写流程?

由于AO是F通过保存被执行的写命令来记录数据库状态,随时间流失,AOF文件中的内容会越来越多,体积越来越大,且会包含很多无用数据,比如新增键后又删除改键,AOF总是会保存这两个操作,实际上该键被删除已经不需要记录了,这种些命令显然没有存在的必要。
因此,为了解决

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值