Redis 的持久化机制是什么?各自的优缺点是什么?

[复制链接]
查看6170 | 回复0 | 2022-4-9 16:31:01 | 显示全部楼层 |阅读模式
面试官今天要不来聊聊Redis的持久化机制吧?
0 j+ W6 y' M1 y$ W% u候选者:嗯,没问题的
; i' g# d) k( n% P8 Z$ e候选者:在上一次面试已经说过了Redis是基于内存的
/ s. \4 B& j: l+ F/ e0 Y7 S候选者:假设我们不做任何操作,只要Redis服务器重启(或者中途故障挂掉了),那内存的数据就会没掉
' q! z9 e% g" j, B1 P' S候选者:我们作为使用方,肯定是不想Redis里头的数据会丢掉
% g0 i- C( s9 j* j+ n2 o. D候选者:所以Redis提供了持久化机制给我们用,分别是RDB和AOF# H# I. M2 T: ~& G" `9 p; q0 J9 D8 f
+ T! P4 ]4 a# G3 ^2 b% z6 c* G: k! [
Redis 的持久化机制是什么?各自的优缺点是什么?-1.jpg * t4 q3 U% T1 d3 g, \6 X4 F

: X7 [* |% `+ t* P  {% {" o8 V候选者:RDB指的就是:根据我们自己配置的时间或者手动去执行BGSAVE或SAVE命令,Redis就会去生成RDB文件0 U" s/ Z7 s$ E1 r
候选者:这个RDB文件实际上就是一个经过压缩的二进制文件,Redis可以通过这个文件在启动的时候来还原我们的数据
7 s. W0 W2 y+ h2 F5 K候选者:而AOF则是把Redis服务器接收到的所有写命令都记录到日志中
& d% V8 B( ^" C* ~# a3 n! j7 ?9 @: A候选者:Redis重跑一遍这个记录下的日志文件,就相当于还原了数据' ?- z6 S  Q1 s* ]

* F  C) y3 x$ ]+ s5 J6 g+ n2 L Redis 的持久化机制是什么?各自的优缺点是什么?-2.jpg * T7 m. F2 U' b1 l0 K
% N8 \$ e$ G  P
面试官那我就想问了,你上次不是说Redis是单线程吗/ Z, q- y" F% k4 T8 U8 S! V
面试官那比如你说的RDB,它会执行SAVE或BESAVE命令,生成文件
: M" v  u, g" D9 M" r2 N面试官那不是非常耗时的吗,那如果只有一个线程处理,那其他的请求不就得等了?
- ~9 s9 j! S9 }+ B! E; |候选者:嗯,没错,Redis是单线程的。( G/ w! _6 R7 t3 z: o
候选者:以RDB持久化的过程为例,假设我们在配置上是定时去执行RDB存储
/ H" a. k' C0 H! U候选者:Redis有自己的一套事件处理机制,主要处理文件事件(命令请求和应答等等)和时间事件(RDB定时持久化、清理过期的Key等的)3 M- L2 M7 ]5 ~, O# y4 {! }
候选者:所以,定时的RDB实际上就是一个时间事件
7 _  D& M+ \( w0 S候选者:线程不停地轮询就绪的事件,发现RDB的事件可执行时,则调用BGSAVE命令: U$ L* B5 L5 A; x6 p
候选者:而BGSAVE命令实际上会fork出一个子进程来进行完成持久化(生成RDB文件)
  a1 O/ v* B. N: ?* z% y- {8 y) e
6 ?6 w5 E# Y  j# _. f+ w! H% G Redis 的持久化机制是什么?各自的优缺点是什么?-3.jpg
" _% {, v& q5 b& m4 b0 S
* o# c2 W- o( z0 E候选者:在fork的过程中,父进程(主线程)肯定是阻塞的。
6 N8 A1 H( H9 K- x0 X7 m  ]候选者:但fork完之后,是fork出来的子进程去完成持久化。处理请求的进程该干嘛的就干嘛
1 W. L) X5 D# I" S6 y3 k候选者:所以说啊,Redis是单线程,理解是没错的,但没说人家不能fork进程来处理事情呀,对不对+ H, l' z( }% h$ Z# T) i
候选者:还有就是,其实Redis在较新的版本中,有些地方都使用了多线程来进行处理
: \8 x: i+ s/ o5 Q0 J3 R, S候选者:比如说,一些删除的操作(UNLINK、FLUSHALL ASYNC等等)还有Redis 6.x 之后对网络数据的解析都用了多线程处理了。( ^$ U  [& l- e9 P; s7 W2 h
候选者:只不过,核心的处理命令请求和响应还是单线程。% L# W/ S4 |  R, i
' O1 W3 b% B+ L1 c! M  O
Redis 的持久化机制是什么?各自的优缺点是什么?-4.jpg
1 l* K$ m# ]0 ~# _& K* `% |7 R) `
2 W- G- J3 m2 m3 Y' m' ]* C6 \0 H面试官那AOF呢?AOF不是也要写文件吗?难道也是fork 了个子进程去做的?
; i7 A- b: d* m* K0 E$ j6 n候选者:emm,不是的。AOF是在命令执行完之后,把命令写在buffer缓冲区的(直接追加写)3 n! `0 E7 E* F: s
候选者:那想要持久化,肯定得存盘嘛。Redis提供了几种策略供我们选择什么时候把缓冲区的数据写到磁盘; D0 R4 Y+ v4 z8 t- e8 h1 K* p
候选者:我记得有:每秒一次/每条命令都执行/从不存盘;一般我们会选每秒一次& v9 n2 R7 t0 }9 D
候选者:Redis会启一个线程去刷盘,也不是用主线程去干的
9 v6 i& W& n3 Q1 S( |* o; J: m面试官那如果把执行过的命令都存起来
; L# T5 |* R% \& w# Q. ?面试官等启动的时候是可以再把这些写命令再执行一遍,达到恢复数据的效果
2 R+ H% a; o8 r8 I* L! F面试官这样会有什么样的问题吗?) Y1 c$ M  H, y: s4 ?4 E& q# G
候选者:嗯,问题就是,如果这些写入磁盘的「命令集合」不做任何处理,那该「命令集合」就会一直膨胀
  w  d0 W4 k9 |/ }& C候选者:其实就是该文件会变得非常大
  U  g2 {5 \- A) ~% G& b( |候选者:Redis当然也考虑了这一点,它会fork个子进程会对「原始」命令集合进行重写& \  t$ i8 a9 q! ^
候选者:说白了就是会压缩,压缩完了之后只要替换原始文件就好了
( {  X/ K( A; _" e( w
( R# c& e' i7 _8 U1 v1 s Redis 的持久化机制是什么?各自的优缺点是什么?-5.jpg
: s/ ~' s5 I2 W  N5 e
1 {2 w; G7 b/ c9 c2 C& q面试官那我又想问了,既然它是fork一个进程来对AOF进行重写的
6 U  d6 n, e9 }2 O面试官前面你也提到了再fork时,主进程是阻塞的,但fork后,主进程会继续接收命令" z! R$ w0 s1 H
面试官你是说重写完(压缩)会进行文件覆盖2 H% ?$ p4 A3 T
面试官那这样不会丢数据吗?毕竟主进程在fork之后是一直会接收命令的
5 Z. J. M9 {  d0 F候选者:哦,我明白你的意思了。
, E" K- F" `7 ~( r7 @: b- H& q, f候选者:其实做法很简单啊,在fork子进程之后,把新接收到命令再写到另一个缓冲区不就好了吗0 t7 @) [) C6 i8 _1 ]1 z
面试官:可以
. Y; E! O) @5 ~9 }  G面试官:那AOF和RDB用哪一个呢?
# [% B% Y' ~3 |) z! `6 N2 V! h候选者:主要是看业务场景吧,我们这边是基于Redis自研了一套key-value存储$ ~" ?/ _. a2 b. L4 k5 e
面试官自研的?你们的Redis架构是什么?6 i" _! a+ n( n
候选者:别别别,当我没说。就是开源的,开源的。我们回到RDB和AOF上吧。; L+ Z2 |- h- A" [9 n9 ^7 n
候选者:在新增namespace(实例) 的时候也会让你选择对应的使用场景
$ |& A; g3 @0 b( w% m7 ]7 n; ?0 F候选者:就是会让你通过不同的应用场景进行配置选择" D, U$ K4 ]  T$ a# L1 N
候选者:比如说,业务上是允许重启时部分数据丢失的,那RDB就够用了(:
; K$ t- ?3 @, x1 o" }) T; s候选者:RDB在启动的时候恢复数据会比AOF快很多
* T4 @; @: f' N# J6 l候选者:在Redis4.0以后也支持了AOF和RDB混合5 Z' E+ Z. i0 i% Y
5 E6 V/ t% R/ A6 o
Redis 的持久化机制是什么?各自的优缺点是什么?-6.jpg
* f- r: ]1 Q9 k+ @, e
+ l! d& N0 Y" L) |) P  n7 X( c候选者:在官网是不建议仅仅只使用AOF的,如果对数据丢失容忍度是有要求的,建议是开启AOF+RDB一起用
8 {2 k$ V* {1 D( f; ]候选者:总的来说,不同的场景使用不同的持久化策略吧
/ R+ o: Y& ?( u  v) \4 z面试官:了解; @4 }9 x' H1 X2 p1 M  F/ \0 Q  y' o
面试官顺便我想问下,假如Redis的内存满了,但业务还在写数据,会怎么样?
4 X. d9 v# k+ x% P) ?候选者:嗯,这个问题我也遇到过* g2 u; p, g3 |+ F# j2 X7 e
候选者:一般来说,我们会淘汰那些「不活跃」的数据,然后把新的数据写进去
1 J0 n8 K; {3 c  @* ]1 g候选者:更多情况下,还是做好对应的监控和容量的考量吧
, J- b  H2 f# m候选者:等容量达到阈值的时候,及时发现和扩容2 Q8 O1 @: k, @' ^8 y8 p
面试官:你这懂得有点多啊- p. t. \4 u$ h- o( n
本文总结
, D$ \2 ~6 z' W( X

    / U: B' i% X) s' L6 E, D4 T
  • Redis持久化机制:RDB和AOF% g5 P3 {+ ?5 s  q8 y* U
  • RDB持久化:定时任务,BGSAVE命令 fork一个子进程生成RDB文件(二进制)
    * @( V- |- `9 Z  M+ Z3 f" I
  • AOF持久化:根据配置将写命令存储至日志文件中,顺序写&&异步刷盘(子线程),重写AOF文件也是需要 fork 子进程。Redis4.0之后支持混合持久化,用什么持久化机制看业务场景% ?% O% e6 z& @# A- [
* R  Y6 }' h! V2 ~3 x$ P
Redis 的持久化机制是什么?各自的优缺点是什么?-7.jpg
  e( o+ F, Q' D我最近一直在连载《对线面试官》系列,目前已经连载38篇啦!一个说人话的面试系列!
$ x! \# @' f6 _( y8 t- l
      F! C5 @5 u% a, A# J( x% k# B
  • 【对线面试官】HTTP2 \% w3 B3 I5 P' T
  • 【对线面试官】Java注解
    6 \, E7 `) o9 M3 ~; c+ T" O
  • 【对线面试官】Java泛型( E4 l/ X2 T3 J: s: X1 N" `9 o
  • 【对线面试官】 Java NIO' I3 q! V! A' k) s+ u$ \1 `
  • 【对线面试官】Java反射 && 动态代理; k: G) _, _1 T6 |
  • 【对线面试官】多线程基础2 A. m% C% T  O9 @0 S2 w
  • 【对线面试官】 CAS
    4 V7 Y0 X/ S# K  k  Q
  • 【对线面试官】synchronized
    6 t! ?: M. s7 I/ I
  • 【对线面试官】AQS&&ReentrantLock- E4 |2 I/ W6 B
  • 【对线面试官】线程池
    4 p' x  M5 b. r4 G" z( r1 ^) c: V2 G
  • 【对线面试官】ThreadLocal9 N9 O' d; g9 q  k
  • 【对线面试官】CountDownLatch和CyclicBarrier
    / Q* [0 P) \9 H/ m( v2 O- v8 w; y
  • 【对线面试官】为什么需要Java内存模型?. D4 E& D  Z0 C' [0 W# e0 A: ?
  • 【对线面试官】深入浅出 Java 内存模型
    ' I3 r% w+ x2 p
  • 【对线面试官】Java从编译到执行,发生了什么?$ S$ j& X0 t3 `# [: R: o" y. d
  • 【对线面试官】双亲委派机制: `7 M* i) m, y0 Z2 N8 O
  • 【对线面试官】JVM内存结构
    # j: |% r  O4 K2 O- K
  • 【对线面试官】垃圾回收机制
    5 d4 L. @/ ^" u  T5 T8 g( J4 }$ u: Z
  • 【对线面试官】CMS垃圾回收器1 d- N. {- l% m9 ~
  • 【对线面试官】G1垃圾收集器
    ) S6 v; r2 y6 p, e6 }0 G7 y, H
  • 【对线面试官】JVM调优
    : e3 D/ u" P- R. d8 \  r
  • 【对线面试官】List
    . N$ R2 O1 T+ I7 Z6 V
  • 【对线面试官】Map- u. k  s8 P/ R+ I  ^# i3 M
  • 【对线面试官】SpringMVC
    - b5 [: V0 H0 j+ G
  • 【对线面试官】Spring基础6 K- Z' B# w  W& c. x  e! j
  • 【对线面试官】SpringBean生命周期
    / c% o& f: k. G3 Q2 q
  • 【对线面试官】Redis基础) d/ W$ N/ G1 }9 k* s" M: \
  • 【对线面试官】Redis持久化
    $ K$ I; `! G! M: |7 b
  • 【对线面试官】Redis主从架构) U( i2 X- d$ p5 t
  • 【对线面试官】Redis分片集群
    0 h% ^) l% g# X& T  T
  • 【对线面试官】Kafka基础
    4 W# J) b6 a- }3 b! N0 G
  • 【对线面试官】使用Kafka会考虑什么问题?# c5 ?/ j2 ?7 ~: B3 J
  • 【对线面试官】MySQL索引
    7 n6 e' I! n5 Q" l, W+ J
  • 【对线面试官】MySQL 事务&&锁机制&&MVCC/ h( A" {: ?' M1 f5 P- D; c! n
  • 【对线面试官】MySQL调优
    , G6 N, Q% u2 A- P$ U
  • 【对线面试官】如何实现幂等和去重?: m' I  `! i; w
  • 【对线面试官】系统需求多变时,如何设计$ _- {1 m. b3 a4 ?
  • 【对线面试官】设计模式
    " F( O! }7 w" r) D9 x, _
  • ...$ I' x* X' }# n1 I* H
【大厂面试知识点】、【简历模板】、【原创文章】电子书,共有1263页
, H* ?8 t( Z0 v6 d我把这些上传到网盘,你们有需要直接下载就好了。做到这份上了,不会还想白嫖吧点赞转发又不用钱。
% \  g4 c# C: K8 {% W8 w: g; {
$ T8 s  Z$ N; k3 L# s Redis 的持久化机制是什么?各自的优缺点是什么?-8.jpg   x' [- Z/ q, ]+ X  l* T& _

. S7 K' R1 ]# [, `  u& t( s, M! v链接:pan.baidu.com/s/1pQTuKBYs… 密码:3wom
8 a9 o/ J2 w% n& ~不会有人刷到这还想白嫖吧?不会吧?点赞对真的我很重要!要不加个关注? @Java3y
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

204

金钱

0

收听

0

听众
性别

新手上路

金钱
204 元