Redis基础知识+RDB+AOF(面试)

这里写自定义目录标题

本章节当中重点解释Redis当中的特性(以及面试当中的相关问题)

Redis (in-memory data store)

Redis用于分布式系统中 如果是单机程序,直接使用变量存储数据,比redis更优选择

从名称当中可以知道,Redis值存储在内存当中的,通过网络把自己的内存中的变量给别的主机使用

Redis是一个在内存当中存储数据的中间件,用于作为数据库或者是数据库缓存

Redis是一种典型的非关系型数据库

Redis特性

  1. In-memory data structures:在内存当中存储数据
  2. Programability:针对Redis操作,可以简单交互命令进行操作,也可以是脚本操作 Lua编程语言
  3. Extensibility:可以在Redis原有功能基础上再进行扩展,Redis提供了一组API
  4. Persistence:持久化,内存当中的数据是比较容易丢失的,Redis提供了两种持久化的方式:RDB与AOF(后续解释)这两种策略可以将内存当中数据保存在硬盘上
  5. Clustering:集群性:引入多个主机,部署多个Redis节点,每个Redis存储一份数据
  6. High availability:高可用性哨兵机制
  7. Replication:主从复制
  8. 基于键值对的数据存储

速度快

为什么Redis的速度是非常快的?

  1. Redis的所有的数据都是存放在内存当中的,比访问硬盘的速度要快上很多
  2. Redis的核心逻辑都是比较简单的逻辑,本身不会吃很多的内存资源
  3. 从网络角度上来说,Redis使用的是IO多路复用,使用一个线程,管理多个socket
  4. Redis使用的是单线程的模型,减少了不必要的线程之间的竞争开销

最大的劣势与MySQL相比 :存储空间是有限的

有没有存储的又大又快:Redis与MySQL相结合的方式

Redis的应用场景

  1. Real-time data store:redis作为数据库(如果只有Redis数据库,那么就需要考虑数据不能丢失的问题,但是此处应该最先考虑的是数据量的大)
  2. Caching&session storage:根据二八原则,把热点数据提取出来,存储在Redis当中 (cookie实现了用户信息保存,存储了用户的身份标识)
  3. Streaming & messaging:消息队列(基于消息队列可以实现网络当中的生产者、消费者模型)

Redis常见的数据类型

简单介绍+命令的时间复杂度,具体的使用后续会有文章专门解释

基本的全局命令

KEYS

h?llo:hello,hallo

h*ll:hllo,haaaaall

h[ae]llo:表示这块可以匹配a/e

h[^e]ll:表示除了e其他的匹配

时间复杂度:O(N)

EXISTS

判断某个key是否存在(也可以判断多个key是否存在)

时间复杂度:O(1);有几个key,1就需要变成几

DEL

删除指定的key

时间复杂度:O(1);有几个key,1就需要变成几

EXPIRE

为指定的key添加秒级的过期时间,超出时间之后会自动被删除

时间复杂度:O(1)

TTL

存活的时间,(网络原理当中也有一个TTL那个是到达的次数)

TYPE

返回key所对应的数据类型,其实说的是value的类型,key的类型都是string

时间复杂度:O(1)

Redis数据结构

String hash list set zset
具体使用,相关底层编码问题,其他篇章介绍

常见面试题

  1. 过期机制是怎样实现的,Redis当中会有很多的key,怎样判读出当前这个key快要过期
    定期删除 :每次抽取一部分,验证过期时间,保证抽取检查的过程足够快
    惰性删除 :假设这个key已经到过期时间了,但是暂时没有删除,后面再次访问的时候恰好用到这个key,此刻就会让redis服务器触发删除key的操作

    也有可能会出现大量的过期key没有删除,从而占用内存空间,提供了一种内存淘汰机制

    还有一种是定时删除(但是Redis没有采取这种策略):1. 基于优先级队列/堆 2. 基于时间轮

  2. 为什么Redis是单线程但是还会这么快(几乎是必考)

    可以将其归纳为3点
    纯内存访问 :所有的数据都存放在内存当中,是访问快速的基础
    Redis的核心功能要比数据库核心功能会更简单 :排序,大量的存储Redis没有那么精通
    单线程避免了线程切换和竞态产生的消耗 :单线程会减少竞争产生的消耗
    非阻塞IO:Redis使用epoll作为I/O多路复用技术的实现

    Linux提供了IO多路复用主要是三套API:select,poll,epoll(相当于是事件通知/回调机制)

持久化

Redis支持RDB和AOF两种持久化机制

Redis使用的是自定义的应用层协议:RESP protocol spec

该协议的优点是:简单易实现,快速进行解析,肉眼可读,传输层基于TCP实现,但是没有强耦合

协议格式:请求,客户端给服务器发送的是redis命令(bulk string数组的形式发送的)

响应:Simple String :+ "+OK\r\n":服务器就会写入tcp,socket

Error:- "-Error message\r\n"

Integers::":1000\r\n"

Bulk String :可以传输二进制

Arrays:数组

RDB

RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发可以是手动触发/自动触发

类似于在道路上开车时,如果超速了,就会生成超速的快照,截图那种

触发机制

手动触发分别对应save与bgsave

save:阻塞当前Redis服务器,Redis全力以赴,其他的客户端命令就没有办法执行,会造成内存长时间阻塞,基本不采用

bgsave:Redis创建fork紫禁城,RDB持久化过程由子进程负责

Redis内部所有涉及RDB操作都类似与bgsave的形式

自动才是更为常见的

  1. 使用save配置,如"save m n"表示m秒内数据集发生了n次修改,自动进行RDB持久化
  2. 从节点进行全量复制,主节点自动进行RDB持久化,随后RDB文件内容发给从节点
  3. 执行shutdown命令时,执行RDB持久化

流程说明

  1. 执行命令,会判断是否有其他进程执行RDB,如果存在直接返回
  2. 父进程执行fork创建子进程,父进程会阻塞,
  3. 父进程fork完成之后,父进程就可以进行其他的命令了
  4. 子进程创建的RDB文件,生成快照过程,父进程继续进行客户端的请求
  5. 子进程完成后会通知父进程,子进程就会结束
    生成的rdb文件是存放在redis的工作目录当中的

RDB文件的处理

保存: RDB文件保存再dir配置指定的目录
压缩: Redis默认采用LZF算法对生成的RDB文件做压缩处理

RDB的优缺点

RDB是一个紧凑的二进制文件,非常适合备份,全量复制等场景

Redis加载RDB恢复数据远远快于AOF的方式

但是RDB没有办法做到实时持久化,因为需要执行fork操作,属于重量级的操作,频繁之后,执行成本会变高

AOF

配置默认时不开启的,开启AOF之后,RDB就不生效了

流程说明

  1. 所有的写入命令都会追加到缓冲区当中

  2. AOF会根据对应的策略向硬盘做出同步操作

  3. 随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的

  4. 当Redis服务器启动的时候,需要加载AOF文件进行数据的恢复

    AOF使用缓冲区,避免了每次从内存读写变成IO读写,性能会受到影响

文件同步

AOF文件缓冲区同步策略

可配置的值 说明
always 命令写入缓冲区之后,调用同步,完成后返回(频率最高,可靠性最高,性能最低)
everysec 写入缓冲区后write,不进行同步,每秒由同步线程进行同步(频率低一些,可靠性也降低,总能会提高)
no 写入缓冲区之后执行write,由OS控制同步(频率最低,可靠性最低,性能最高)

write与fsync说明:

write:会触发延迟机制,write操作在写入系统缓冲区之后,立刻返回,同步硬盘操作依赖与系统调度机制

fsync:针对单个文件操作,做强制硬盘同步,fsync将阻塞直到数据写入硬盘当中

重写机制

随着命令不断写入AOF,文件会越来越大,Redis引入了AOF重写机制压缩文件体积。AOF文件重写是把Redis进程内的数据转化为写命令同步到新的AOF文件

重写后的AOF为什么可以变小

  1. 进程内已超时的数据不再写入文件

  2. 旧的AOF中的无效命令,例如del、hdel等会删除,只需要保存最终版本

  3. 多条写操作合并为一条

    AOF重写过程可以分为手动触发和自动触发:
    手动触发:调用 bgrewriteaof 命令
    自动触发:根据配置当中的自动触发参数,1. 表示触发重写时AOF的最小文件大小 2. 代表当前AOF占用大小相比较上次重写时增加的比例

AOF重写流程

此刻时手动的情况

  1. 执行AOF重写请求
  2. 父进程执行fork创建子进程,而父进程接收处理新请求
  3. 重写(不关心AOF原来,只关心内存最终的数据状态)
    a. 主进程fork之后,继续相应其他命令,所有修改操作写入AOF缓冲区,并根据appendfsync策略进行同步到因公安,保证旧的AOF文件机制正确
    b. 子进程只有fork之前的所有的内存信息,父进程需要将fork之后这段时间的修改操作写入到AOF缓冲区当中
  4. 子进程根据内存快照,将命令合并到新的AOF文件当中
  5. 子进程完成重写
    a. 新文件写入后,子进程发送信号给父进程
    b. 父进程把AOF重写缓冲区内临时保存的命令追加到AOF文件当中
    c. 用心的AOF文件替换老的AOF文件

启动时数据恢复

当Redis启动时,会根据RDB与AOF文件内容,进行数据恢复

AOF按照文本方式写入文件的,但文本方式后续加载成本是比较高的

Redis引入"混合持久化"方式结合RDB与AOF的特点,按照AOF方式,每个请求/操作,记录文件

触发AOF重写之后,会把当前内存状态,按照RDB二进制格式写入新的AOF文件当中,后续操作,仍然是AOF文本追加到后面
Redis中同时有AOF与RDB:以AOF为主,RDB忽略

相关推荐
周杰伦_Jay3 小时前
【Eino框架】Go语言驱动的LLM应用开发新范式
开发语言·后端·golang
毕设源码-赖学姐3 小时前
【开题答辩全过程】以 高校排课系统的优化设计与实现为例,包含答辩的问题和答案
java·eclipse
q_19132846953 小时前
基于SpringBoot2+Vue2的行业知识答题考试系统
java·vue.js·spring boot·mysql·毕业设计·计算机毕业设计·演示文稿
兔丝3 小时前
Redis + ThinkPHP 实战学习手册(含秒杀场景)
后端
上78将3 小时前
Java中既有编译执行又有解释执行,这个怎么理解?
java·开发语言
Mr_Xuhhh3 小时前
JAVA期末重点
java·开发语言·python
lang201509283 小时前
深入解析Kafka Broker核心读写机制
分布式·kafka
a程序小傲3 小时前
小红书Java面试被问:java创建对象有哪些方式?
java·开发语言·面试
代码or搬砖3 小时前
Spring Cache讲解
java·后端·spring