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

[复制链接]
查看6169 | 回复0 | 2022-4-9 16:31:01 | 显示全部楼层 |阅读模式
面试官今天要不来聊聊Redis的持久化机制吧?3 |! i* h. d4 s1 A
候选者:嗯,没问题的) m8 R  I/ A- G9 Z8 L7 ~
候选者:在上一次面试已经说过了Redis是基于内存的
" ^$ O) `4 b& O3 d6 \候选者:假设我们不做任何操作,只要Redis服务器重启(或者中途故障挂掉了),那内存的数据就会没掉
; b4 |7 Z' {' r候选者:我们作为使用方,肯定是不想Redis里头的数据会丢掉$ e* e. Z+ {8 _7 k) b9 w- U
候选者:所以Redis提供了持久化机制给我们用,分别是RDB和AOF8 T  x8 S. b& _5 Z$ F- B; ?/ Q
, H0 L  a) J. x# `9 ]+ e+ c
Redis 的持久化机制是什么?各自的优缺点是什么?-1.jpg ) h- J. V- J, H+ \  i( a& n% ~: U

/ p3 w2 c7 i) R* y候选者:RDB指的就是:根据我们自己配置的时间或者手动去执行BGSAVE或SAVE命令,Redis就会去生成RDB文件  X, k6 ]% @! A8 p3 {8 t4 A
候选者:这个RDB文件实际上就是一个经过压缩的二进制文件,Redis可以通过这个文件在启动的时候来还原我们的数据* d) C2 B8 U; c. q' Y
候选者:而AOF则是把Redis服务器接收到的所有写命令都记录到日志中
% J8 I7 A) L# h% y5 g% Z# b候选者:Redis重跑一遍这个记录下的日志文件,就相当于还原了数据
; V3 A, [+ ?- m" o; O1 s  }- _! Z1 K6 f3 B! `6 P
Redis 的持久化机制是什么?各自的优缺点是什么?-2.jpg
* G- y: x+ v6 S1 O& ~5 r% O1 W! u6 R6 T+ P
面试官那我就想问了,你上次不是说Redis是单线程吗9 E0 i: a, R: B0 B  q* E
面试官那比如你说的RDB,它会执行SAVE或BESAVE命令,生成文件' C" U/ F7 v2 d2 `$ s$ {# D
面试官那不是非常耗时的吗,那如果只有一个线程处理,那其他的请求不就得等了?
  W  c2 r+ p# S8 z候选者:嗯,没错,Redis是单线程的。
; w+ _& y) r8 V3 y4 K6 H" S候选者:以RDB持久化的过程为例,假设我们在配置上是定时去执行RDB存储0 L$ a2 m; j, W# f
候选者:Redis有自己的一套事件处理机制,主要处理文件事件(命令请求和应答等等)和时间事件(RDB定时持久化、清理过期的Key等的)
* u1 H- z; ?+ ]; v候选者:所以,定时的RDB实际上就是一个时间事件
" N" N) s4 {" l! I候选者:线程不停地轮询就绪的事件,发现RDB的事件可执行时,则调用BGSAVE命令
' U, |. e1 Z3 K. d+ ~% J候选者:而BGSAVE命令实际上会fork出一个子进程来进行完成持久化(生成RDB文件)
0 k, K8 c+ x* `3 p( x" R. t. {! p1 z3 z8 e$ a
Redis 的持久化机制是什么?各自的优缺点是什么?-3.jpg
- V0 P9 R& S4 l2 ^. ~1 z9 Y; T/ ?5 f/ ^  I& n
候选者:在fork的过程中,父进程(主线程)肯定是阻塞的。! n; z% N. }; j( O- r
候选者:但fork完之后,是fork出来的子进程去完成持久化。处理请求的进程该干嘛的就干嘛/ T  P+ `8 U' S4 U/ g" h
候选者:所以说啊,Redis是单线程,理解是没错的,但没说人家不能fork进程来处理事情呀,对不对
, \# R, B' s1 S0 Z" B/ @候选者:还有就是,其实Redis在较新的版本中,有些地方都使用了多线程来进行处理
2 s: U7 H+ Y8 Y4 X; X候选者:比如说,一些删除的操作(UNLINK、FLUSHALL ASYNC等等)还有Redis 6.x 之后对网络数据的解析都用了多线程处理了。
3 B% [* ^6 I2 Z候选者:只不过,核心的处理命令请求和响应还是单线程。
+ ?1 X6 Y8 u/ Z* q; H9 q7 K, H* [3 v) W3 B
Redis 的持久化机制是什么?各自的优缺点是什么?-4.jpg   T5 `( X* K* D5 M- {; Z

6 i. x- B2 s; A3 a7 P面试官那AOF呢?AOF不是也要写文件吗?难道也是fork 了个子进程去做的?
4 j! l0 v; M& s9 o9 X+ j! A: a候选者:emm,不是的。AOF是在命令执行完之后,把命令写在buffer缓冲区的(直接追加写)
4 ]% C2 U# @9 q* A( j候选者:那想要持久化,肯定得存盘嘛。Redis提供了几种策略供我们选择什么时候把缓冲区的数据写到磁盘
- ?9 K7 Z( S1 h& i7 ^/ }' D* ~候选者:我记得有:每秒一次/每条命令都执行/从不存盘;一般我们会选每秒一次
  m8 ^: t, w! {( n0 w候选者:Redis会启一个线程去刷盘,也不是用主线程去干的5 e: y, K$ ~" b/ y7 `9 y
面试官那如果把执行过的命令都存起来" S& z& ]! i3 l- l; y
面试官等启动的时候是可以再把这些写命令再执行一遍,达到恢复数据的效果0 u" e: [  S2 A- u9 z$ O
面试官这样会有什么样的问题吗?
) r' |( P& w* @/ Y  Z9 D候选者:嗯,问题就是,如果这些写入磁盘的「命令集合」不做任何处理,那该「命令集合」就会一直膨胀/ }6 m5 R' d1 A, z8 Z( s
候选者:其实就是该文件会变得非常大6 h; T# q, K2 t/ u8 h, ?9 T
候选者:Redis当然也考虑了这一点,它会fork个子进程会对「原始」命令集合进行重写
+ z( _6 u5 v' i1 ~3 Z- D. n5 S2 l候选者:说白了就是会压缩,压缩完了之后只要替换原始文件就好了' Z0 h( `  H2 `' y+ `- p
: h( a9 ^# Z; n/ W$ b8 N
Redis 的持久化机制是什么?各自的优缺点是什么?-5.jpg
& {5 W9 b7 ]; S
9 R. L9 j/ ^8 m* K) M4 q" s7 \面试官那我又想问了,既然它是fork一个进程来对AOF进行重写的1 P3 |5 v! J. v
面试官前面你也提到了再fork时,主进程是阻塞的,但fork后,主进程会继续接收命令
* X% J) _' e9 A/ T" [7 h4 R面试官你是说重写完(压缩)会进行文件覆盖
3 d$ ]) s* z" E6 s3 w面试官那这样不会丢数据吗?毕竟主进程在fork之后是一直会接收命令的
4 m3 G1 {; r" s6 a3 P  a候选者:哦,我明白你的意思了。
; x6 k# _- E$ L4 N: t+ N候选者:其实做法很简单啊,在fork子进程之后,把新接收到命令再写到另一个缓冲区不就好了吗1 y* A2 F( j  E
面试官:可以
5 p3 R& }: q$ W9 ?# J; d面试官:那AOF和RDB用哪一个呢?
: W" Q/ l! [& K% R候选者:主要是看业务场景吧,我们这边是基于Redis自研了一套key-value存储! J9 Z' S' t6 e6 z$ |# o
面试官自研的?你们的Redis架构是什么?
8 W0 A+ J3 x8 n" m, `1 v' E( t候选者:别别别,当我没说。就是开源的,开源的。我们回到RDB和AOF上吧。
. Y1 D4 j% U( n6 w$ m8 F候选者:在新增namespace(实例) 的时候也会让你选择对应的使用场景/ N. G- L1 m- c8 o- n. Q
候选者:就是会让你通过不同的应用场景进行配置选择
; z3 o" B; ?* j- Y4 P候选者:比如说,业务上是允许重启时部分数据丢失的,那RDB就够用了(:! }9 u6 Y$ Z) C$ D0 I! E
候选者:RDB在启动的时候恢复数据会比AOF快很多6 ^2 y# n( i. q( F0 l7 ^  S
候选者:在Redis4.0以后也支持了AOF和RDB混合" n# ^5 c8 ~. I
5 ~( \7 P/ k! s. q2 `
Redis 的持久化机制是什么?各自的优缺点是什么?-6.jpg
; T3 e/ P1 X: [# @4 ?" H1 `7 I! w  e" c8 ]: E* S
候选者:在官网是不建议仅仅只使用AOF的,如果对数据丢失容忍度是有要求的,建议是开启AOF+RDB一起用
4 B( E8 I* u$ G, |2 j: [8 n候选者:总的来说,不同的场景使用不同的持久化策略吧
1 w# e9 y( V+ m) q- u" b4 }" b4 f面试官:了解
$ q  c: M% G# A- l5 X& R面试官顺便我想问下,假如Redis的内存满了,但业务还在写数据,会怎么样?, Y' q! v- g# X* b: l+ S/ d6 Q
候选者:嗯,这个问题我也遇到过
# `& O+ k0 U! F' Q. o7 ^候选者:一般来说,我们会淘汰那些「不活跃」的数据,然后把新的数据写进去% c0 N. z- P# [. {
候选者:更多情况下,还是做好对应的监控和容量的考量吧) A+ U0 }! u1 {% u3 H( T
候选者:等容量达到阈值的时候,及时发现和扩容
7 L5 Q7 M  m0 O# ~5 S面试官:你这懂得有点多啊
* k+ a  ]) |6 \- i* k$ e. J; E" b本文总结
2 P0 [; b) P8 S. `% r

    4 }/ ^, k9 L  b8 L9 B. k, x
  • Redis持久化机制:RDB和AOF
    1 \' N6 |# q( f
  • RDB持久化:定时任务,BGSAVE命令 fork一个子进程生成RDB文件(二进制)% w/ U" J9 m. x1 t+ z# \
  • AOF持久化:根据配置将写命令存储至日志文件中,顺序写&&异步刷盘(子线程),重写AOF文件也是需要 fork 子进程。Redis4.0之后支持混合持久化,用什么持久化机制看业务场景
    + _! i5 N4 y2 [

# H' J5 Z6 T, P' v4 H Redis 的持久化机制是什么?各自的优缺点是什么?-7.jpg   h, b0 i4 ?2 ^1 u4 a
我最近一直在连载《对线面试官》系列,目前已经连载38篇啦!一个说人话的面试系列!) J  R$ O  O+ N' W; c, |
    % ~# P: {% `8 E( o8 x0 s% N
  • 【对线面试官】HTTP! T; H4 b( k$ f; T. E# U% b1 }
  • 【对线面试官】Java注解7 `$ `4 C" v9 P: B( e/ f
  • 【对线面试官】Java泛型8 P6 M$ ~7 d% Q1 A: v
  • 【对线面试官】 Java NIO
    * l5 C7 @, H& w: P
  • 【对线面试官】Java反射 && 动态代理- M0 D2 j: c' R, x% J$ q! @
  • 【对线面试官】多线程基础
    4 \; Y/ ^! e9 X( \" N* J+ {1 ~
  • 【对线面试官】 CAS( B( W6 a. @2 S
  • 【对线面试官】synchronized) Y# \9 B  W+ |& J7 f* o
  • 【对线面试官】AQS&&ReentrantLock
    0 p+ o, S  f% [
  • 【对线面试官】线程池7 F4 @5 _0 l* Y. }7 ~- ~
  • 【对线面试官】ThreadLocal" G+ J2 e: h: I, j. F/ `
  • 【对线面试官】CountDownLatch和CyclicBarrier
    / [4 V+ r( N  a1 [
  • 【对线面试官】为什么需要Java内存模型?: C+ l1 o4 ^2 R2 H4 a# S0 S
  • 【对线面试官】深入浅出 Java 内存模型
    * g& U$ ]% {" S" K* E
  • 【对线面试官】Java从编译到执行,发生了什么?6 s' t5 |; o' {$ \: r
  • 【对线面试官】双亲委派机制
    # o: X" h9 O; ^
  • 【对线面试官】JVM内存结构( X, L2 O/ Y8 `+ @# k+ Q
  • 【对线面试官】垃圾回收机制& Z0 \& N7 J# o1 E8 g
  • 【对线面试官】CMS垃圾回收器1 j* a( H# Y  s0 H4 ]6 ~+ ^/ E7 P
  • 【对线面试官】G1垃圾收集器
    & b6 V5 n) r* D* f( J
  • 【对线面试官】JVM调优: t1 u8 w  ]) _6 O. Y  F8 K
  • 【对线面试官】List7 L5 K4 h1 c1 Y
  • 【对线面试官】Map; {# L0 ]) ^3 k' l
  • 【对线面试官】SpringMVC& |0 T( b2 b: ^% o& J8 m, w& i! i
  • 【对线面试官】Spring基础
    ( y5 `' M" G5 r& v- |
  • 【对线面试官】SpringBean生命周期6 ?$ y! p3 ~  Q+ S- e; |  j
  • 【对线面试官】Redis基础
    6 F3 D- R7 h: X/ P4 O. g
  • 【对线面试官】Redis持久化, @3 D7 P0 S: E# `3 I
  • 【对线面试官】Redis主从架构
    ! I0 x5 q7 j$ \- q: o
  • 【对线面试官】Redis分片集群
    4 F* ]' d6 G% Q, F: t  e) b3 z
  • 【对线面试官】Kafka基础
    9 a) G) b7 g; X, \
  • 【对线面试官】使用Kafka会考虑什么问题?
    2 m/ y; R, S4 ~8 T  J6 }9 g
  • 【对线面试官】MySQL索引
    ) h' Q0 j5 P0 y0 d* q9 h
  • 【对线面试官】MySQL 事务&&锁机制&&MVCC
    4 B# K, z' Q6 e% ?( N3 |* u
  • 【对线面试官】MySQL调优* y) J' p- d* k3 |+ `
  • 【对线面试官】如何实现幂等和去重?0 ]/ R" {8 ]5 M8 q
  • 【对线面试官】系统需求多变时,如何设计
    5 N: J) }2 Z" {2 S+ @) H4 R8 q9 V
  • 【对线面试官】设计模式$ ^  K8 {8 z, w0 U/ A
  • ...6 q0 u* L; p% a
【大厂面试知识点】、【简历模板】、【原创文章】电子书,共有1263页7 w$ @+ c1 B4 y& Q- w! E
我把这些上传到网盘,你们有需要直接下载就好了。做到这份上了,不会还想白嫖吧点赞转发又不用钱。
# f" e( z( ~! B3 H* y" ]! Q  {# t) u5 ~( j8 S  d0 x$ y3 V
Redis 的持久化机制是什么?各自的优缺点是什么?-8.jpg 7 q0 O& u2 x  |. C8 x3 _
2 |8 Z  r( Q( F; P- G
链接:pan.baidu.com/s/1pQTuKBYs… 密码:3wom1 C$ k7 n9 q# u3 o; W- t
不会有人刷到这还想白嫖吧?不会吧?点赞对真的我很重要!要不加个关注? @Java3y
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

204

金钱

0

收听

0

听众
性别

新手上路

金钱
204 元