加入收藏 | 设为首页 | 会员中心 | 我要投稿 泰州站长网 (https://www.0523zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 创业 > 点评 > 正文

Redis面试宝典-持久化篇

发布时间:2022-08-25 20:10:14 所属栏目:点评 来源:
导读: 一:Redis持久化有哪些方式?二:RDB持久化触发方式有哪些?三:RDB持久化优缺点?四:简述bgsave过程?五:简述AOF工作

一:Redis持久化有哪些方式?二:RDB持久化触发方式有哪些?三:RDB持久化优缺点?四:简述bgsave过程?五:简述AOF工作流程?六:AOF缓冲区同步文件策略有哪些?七:AOF重写触发条件?八:简述AOF重写过程?九:RDB和AOF持久化文件损坏如何处理?

一:Redis持久化有哪些方式?

1.RDB持久化

将当前进程数据生成快照保存到硬盘。

 

2.AOF持久化(append only file)

以独立日志方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。

二:RDB持久化触发方式有哪些?

触发RDB持久化过程分为手动触发和自动触发。

手动触发命令有savebgsave

save命令:阻塞当前Redis服务器,直到RDB过程完成为止,对于内存较大的实例会造成长时间阻塞,线上环境不建议使用,运行save命令对于Redis日志如下:

* DB saved on disk

 

bgsave命令:

Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。

阻塞只发生fork阶段,一般时间较短。运行bgsave命令对应redis日志如下:

* Backgroup saving start by pid xxx

* DB saved on disk

* RDB:0 MB of memory used by copy-on-write

* Backgroup saving terminated with success

 

RDB自动触发有如下几个场景:

1.使用save相关配置,如save m n。表示m秒内数据集存在n次修改时,自动触发bgsave

2.从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点。

3.执行debug reload命令重新加载redis时。

4.默认情况下执行shutdown命令时,如果没有开启AOF持久化功能,则自动执行bgsave


三:RDB持久化优缺点?

优点:

1.RDB是一个紧凑压缩的二进制文件,代表Redis在某个时间点上的数据快照,适合用于备份,全量复制等场景。

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

缺点:

1.RDB方式数据没办法做到实时持久化/秒级持久化。

2.bgsave每次运行都需要执行fork操作创建子进程,属于重量级操作,频繁执行成本过高。

3.RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式RDB版本,存在老版本Redis服务无法兼容新版本RDB格式的问题。

四:简述bgsave过程?

1.执行bgsave命令,Redis父进程判断当前是否存在正在执行的子进程,如果RDB/AOF子进程,如果存在,直接返回。

2.父进程执行fork操作创建子进程,fork操作过程中父进程会阻塞,通过info stats命令查看lastest_fork_usec选项,可以获取最近一个fork操作耗时,单位为微秒。

fork创建子进程不需要拷贝父进程物理内存空间,但是会复制父进程空间内存页表。例如10GBredis进程,需要复制大约20MB的内存页表,因此fork操作耗时跟进程总内存量息息相关。

对于高流量的redis实例OPS(operation per second 每秒操作次数)可达5万以上,如果fork操作耗时在秒级别,将会拖慢redis几万条命令执行。正常情况下fork耗时应该是每GB耗时20毫秒左右。

3.父进程fork完成后,bgsave命令返回”Backgroup saving started“信息并不再阻塞父进程,可以继续响应其他命令。

4.子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。执行lastsave命令可以获取最后一次生成RDB时间,对应inof统计的rdb_last_save_time选项。

5.进程发送信号给父进程表示完成,父进程更新统计信息,具体见info Persistence下的rdb_*相关选项。

五:简述AOF工作流程

1.所有写命令会追加到aof_buf(缓冲区)中。

2.AOF缓存区根据对应的策略向硬盘做同步操作。

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

4.Redis服务器重启时,可以加载AOF文件进行数据恢复。

六:AOF缓冲区同步文件策略有哪些?

由参数appendfsync控制,主要有下面三种配置:

1.always

命令写入aof_buf后调用系统fsync操作同步到AOF文件,fsync完成后返回。

2.everysec

命令写入aof_buf后调用系统write操作,write完成后线程返回。fsync同步文件操作由专门线程每秒调用一次。这也是建议的同步策略,也是默认配置,做到兼顾性能和数据安全性。

3.no

命令写入aof_buf调用系统write操作,不对AOF文件做fsync同步,同步硬盘操作由操作系统负责,通常同步周期最长30秒。

七:AOF重写触发条件?

手动触发:

直接调用bgrewriteaof命令。

 

自动触发:

根据auto-aof-rewrite-min-sizeauto-aof-rewrite-percentage参数确定自动触发时机。

其中:

auto-aof-rewrite-min-size:表示运作AOF重写时文件最小体积,默认64MB

Auto-aof-rewrite-percentage:表示运行AOF文件空间(aof_current_size)和上一次重写后AOF空间(aof_base_size)的比值。

自动触发时间 = aof_current_size > auto-aof-rewrite-min-size && (aof_current_size - aof_base_size) / aof_base_size >= auto-aof-rewrite-percentage

其中aof_current_sizeaof_base_size可以在info Persistence统计信息中查看。

八:简述AOF重写过程

1.执行AOF重写请求。

如果当前进程正在执行AOF重写,请求不执行并返回如下响应:

ERR Backgroud append only file rewriting already in progress

如果当前进程正在执行bgsave操作,重写命令延时到bgsave完成之后再执行,返回如下响应:Background append only file rewriting scheduled

2.父进程执行fork创建子进程,开销等同于bgsave过程。

3.主进程fork操作完成后,继续响应其他命令。所有修改命令依然写入AOF缓冲区,并根据appendfsync策略同步到硬盘,保证原有AOF机制正确性。

由于fork操作运用写时复制技术,子进程只能共享fork操作时的内存数据。由于父进程依然响应命令,Redis使用AOF重写缓冲区保存这部分新数据,防止新AOF文件生成期间丢失这部分数据。

4.子进程根据内存快照,按照命令合并规则写入到新AOF文件。每次批量写入硬盘数据量由配置aof-rewrite-incremental-fsync控制,默认32MB,防止单次刷盘数据过多造成硬盘阻塞。

5.AOF文件写入完成后,子进程发送信号给父进程,父进程更新统计信息,具体见info persistence下的aof_*相关统计。

父进程把AOF重写缓冲区的数据写入到新的AOF文件。

使用新AOF文件替换老文件,完成AOF重写。

九:RDBAOF持久化文件损坏如何处理?

1.RDB文件损坏

RDB文件保存位置在dir配置指定的目录下,文件名通过dbfilename配置指定。

可以通过执行config set dir {newDir}confg set dbfilename {newFileName}动态修改,当下次运行RDB文件会保存到新目录。

当遇到坏盘或磁盘写满等情况,可以通过config set dir {newDir}在线修改文件路径到可用磁盘路径,之后执行bgsave进行磁盘切换,同样适用于AOF持久化文件。

如果在redis启动时加载的RDB文件已经损坏,会拒绝启动,并打印如下日志:

Short read or OOM loading DB. Unrecoverable error,aborting now.

这时可以使用redis提供的redis-check-dump工具检测RDB文件并获取对应的错误报告。

 

2.AOF文件损坏

对于错误格式的AOF文件,先进行备份,然后采用redis-check-aof --fix命令进行修复,修复后使用diff -u对比数据差异,找出丢失数据,有些可以人工修补全。

AOF文件可能存在结尾不完整的情况,比如机器突然断电导致AOF尾部文件命令写入不全。Redis提供了aof-load-truncated配置来兼容这种情况,默认开启。加载AOF时,当遇到此问题时会忽略并继续启动,同时打印如下警告日志:

# !!! Warning: short read while loading the AOF file !!!

# !!! Truncatin the AOF at offset xxxxxx!!!

# AOF loaded anyway because aof-load-truncated is enabled

十:简述AOF追加阻塞

当开启AOF持久化时,常用的同步硬盘的策略是everysec,用于平衡性能和数据安全性。对于这种方式,Redis使用另一条线程每秒执行fsync同步硬盘。当系统硬盘资源繁忙时,会造成redis主线程阻塞。

阻塞流程分析:

1.主线程负责写入AOF缓冲区。

2.AOF线程负责每秒执行一次同步磁盘操作,并记录最近一次同步时间。

3.主线程负责对比上次AOF同步时间:

如果距离上次同步成功时间在2秒内,主线程直接返回。

如果距离上次同步成功时间超过2秒,主线程将会阻塞,直到同步完成。

当发生AOF追加阻塞时,在info Persistence统计中,aof_delayed_fsync指标会累加,查看这个指标方便定位AOF阻塞问题。日志会提示如下内容:

Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete,this may slow down Redis.

 

通过AOF阻塞流程可以发现两个问题:

1.everysec配置最多可能丢失2秒数据,不是1秒。

2.如果系统fsync缓慢,将会导致Redis主线程阻塞,影响效率。

参考:《Redis开发与运维》


(编辑:泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章