Redis常见面试题大白话简答,关于认识Redis及其数据结构、线程模型和持久化

前言

备战面试刷Redis面试题,觉得不能光看还得有输出,于是写文用大白话来回答面试题。

本文仅包括小林coding中Redis面试篇中关于认识Redis、Redis的数据结构、Redis线程模型和Redis持久化部分

写文果然是有助于理解的方式,感觉在倒逼自己思考

参考资料:

小林coding

一、认识Redis

1. 什么是Redis

Redis 是一种键值对数据库,常应用于分布式的场景,作为 MySQL 的缓存,也可以当作消息队列,以及分布式锁等场景。

2. Redis 和 Mencached 有什么区别

它们相同的点是:都是基于内存的数据库,可以当做缓存,都有过期策略,性能都很高。

主要区别是:Redis 支持更多数据类型,而 Mencached 只支持最简单的 key-value。Redis 支持数据持久化。Redis 原生支持分片集群。Redis 还支持发布订阅模型,Lua 脚本等。

3. 为什么选 Redis 作为 MySQL 的缓存

主要是因为 Redis 具备高性能和高并发。高性能指 Redis 是基于内存模型的,操作速度很快。高并发是指 Redis 单机就可破10w,而 MySQL 单机很难破 1w。

高并发的的主要原因有:基于内存的模型,高效的数据结构,单线程的多路复用模型

二、Redis 的数据结构

1. Redis 的数据类型和使用场景有哪些

Redis 的数据结构有

  1. string: 主要用于缓存对象,分布式锁,共享 session 信息等
  2. list:可用作消息队列,但是不支持多个消费者,缺少消息可靠性
  3. hash:可用作缓存对象,购物车(key为用户id,field为商品id,value为商品数量)
  4. set:聚合计算场景,比如点赞,共同关注
  5. zset:排序场景,比如排行榜

以及后续新增的几个特殊类型:

  1. bitmap:用于二值化的统计,比如签到,判断用户登录,判断连续签到等场景
  2. hyperloglog:用于大基数的统计需求,比如百万计用户访问量(UV)的统计
  3. GEO:存储地理位置
  4. Stream:消息队列,相比 list 支持分组消费,消息确认

2. 五种常见的数据结构是怎么实现的

  1. string:实现方式是 SDS,可以存放二进制数据,维护一个长度,所以可以用O(1)得到数据长度,会自动扩容,所以不怕缓冲区溢出
  2. list:旧版双向链表或压缩列表,新版 quicklist
  3. hash:旧版压缩链表或哈希表,新版 listpack 和哈希表
  4. set:哈希表和整数集合
  5. zset:旧版压缩列表或跳表,新版 listpack 和跳表

上述的"或"表示当数据大小到达一定数值时,会使用另一数据结构

三、Redis 线程模型

1. Redis 是单线程的吗

Redis 处理用户请求,解析请求,读写数据,返回数据这一连串操作是由单线程(主线程)完成的。但是 Redis 后台还有其他线程,用于 AOF 刷盘、关闭文件、释放内存

2. Redis 的单线程模型是怎么样的

Redis 在初始化阶段使用 epoll_create 创建一个内核空间的句柄,同时创建服务端,注册连接事件处理函数

Redis 的主线程会进入事件循环,首先处理写发送队列,没有发送完的话注册写事件函数。然后调用 epoll_wait() 等待事件到来。

如果是连接事件,则获取连接,并注册读事件函数;如果是读事件,会将执行结果放到写发送队列;如果是写事件,会继续发送数据,没发送完再继续注册写事件。

3. Redis 采用单线程为什么还这么快

Redis 的大部分操作都在内存中进行;Redis采用单线程模型避免了多线程之间的竞争;I/O多路复用模型使能够一个线程处理多个I/O流

4. Redis 6.0 之前为什么使用单线程

Redis 主要性能瓶颈在于内存大小和网络带宽,增加线程反而增加了切换线程的开销

5. 为什么 Redis 6.0 之后使用多线程

Redis 6.0 之后,在网络传输上使用多线程,提高网络I/O的并行度

四、Redis 持久化

1. Redis 是如何保证数据不丢失的

有三种方式:

  1. RDB:将某一刻的内存数据以二进制保存
  2. AOF:记录每次内存操作,在复原时执行这些操作
  3. 混合持久化:结合 RDB 和 AOF 两种方式的优点,比 AOF 复原更快,比 RDB 更不容易丢数据

2. AOF日志是如何实现的

在客户端发起写操作后,Redis先执行写操作,再将写操作语句写入到AOF日志文件

为什么是执行写操作,再写日志文件

这样有好处就是:不需要进行语法检查,执行失败不会写文件;不会阻塞写操作的执行

也有坏处就是:如果在执行完成和写日志之间宕机了,数据会丢失;写文件操作还是会阻塞后续操作的执行

AOF写回策略有哪些

AOF写回分为几步:写到server.aof_buf缓冲区,系统调用写到内核缓冲区,由操作系统控制写到磁盘

因此写文件操作可以配置不同的策略,比如

Always:每次执行完写操作后将日志写到磁盘,性能开销较大,数据不容易丢失

Everysec:每次执行完写操作会将日志写到内核缓冲区,每秒刷盘,性能开销适中,宕机可能丢失一秒内的数据

No:每次执行完写操作会将日志写到内核缓冲区,由操作系统决定何时刷盘,性能较好,宕机可能丢失更多数据

AOF日志文件过大时,会触发什么机制

AOF日志文件过大时,会触发AOF重写,将当前数据库每一个键值对以一条命令记录到新的AOF文件

AOF重写过程是如何执行的

AOF重写过程由一个子进程执行,可以防止阻塞主进程的执行,同时和主进程共享内存数据,在重写期间,如果主进程对数据做写操作,会触发"写时复制",父子进程就会有独立的数据副本

但是这样会出现父子进程数据不一致,因此在AOF重写过程中,父进程执行写操作后不仅会往写AOF缓冲区,还会写AOF重写缓冲区,在完成重写后,会将AOF重写缓冲区的内容追加到新的AOF文件

3. RDB快照是如何实现的

RDB快照是将某一时刻的内存数据保存下来,然后在宕机的时候可以将数据导入内存进行恢复,执行效率比AOF要高

使用save命令会在主线程生成RDB文件,会造成阻塞,可以使用bgsave使用子进程生成RDB文件,也可以在配置文件配置使用bgsave的条件,如save 3600 1表示3600秒内有一次修改即执行一次bgsave

内存快照这一操作本身是比较耗时的,执行频率太高会对性能有影响,执行频率太低在故障时又可能丢失更多数据

在执行过程中,如果父进程修改数据,会触发"写时复制",两者互不影响,因此bgsave的时候父进程是可以修改数据的

4. 为什么会有混合持久化

由于使用AOF在恢复数据时较慢,使用RDB的话频率又不好把握,为了结合两者的优点,所以使用混合持久化

混合持久化的含义是在AOF重写阶段,将父子进程共享的内存数据以RDB的格式写入到AOF文件,再将AOF重写缓冲区中内容追加到其后,那么该文件前半部分是RDB格式,后半部分是AOF格式

这样的好处是在恢复数据的时候速度比只使用AOF要快,且能保证更少的数据丢失;缺点是混合持久化的AOF文件可读性差,可能在不同版本Redis不兼容

相关推荐
m0_7482509321 分钟前
SQL Server Management Studio的使用
数据库·oracle·性能优化
车载诊断技术23 分钟前
人工智能AI在汽车设计领域的应用探索
数据库·人工智能·网络协议·架构·汽车·是诊断功能配置的核心
没有十八岁27 分钟前
云创智城YunCharge 新能源二轮、四轮充电解决方案(云快充、万马爱充、中电联、OCPP1.6J等多个私有单车、汽车充电协议)之新能源充电行业系统说明书
java·数据库·spring·汽车
pitt19971 小时前
Redis 高可用性:如何让你的缓存一直在线,稳定运行?
redis·redis集群·哨兵·redis主从·redis高可用
萌の鱼2 小时前
leetcode 48. 旋转图像
数据结构·c++·算法·leetcode
爱搞技术的猫猫2 小时前
微店商品详情API接口实战指南:从零实现商品数据自动化获取
大数据·linux·运维·数据库·自动化
大地爱2 小时前
如何使用Spring Boot框架整合Redis:超详细案例教程
spring boot·redis·后端
win水2 小时前
数据结构(初阶)(七)----树和二叉树(堆,堆排序)
数据结构
wanjiazhongqi2 小时前
哈希表和STL —— unorderde_set/unordered_map【复习笔记】
数据结构·c++·哈希算法·散列表
L_cl2 小时前
【Python 数据结构 1.零基础复习】
数据结构·python