一文带你搞懂Redis持久化
访客 发布于2023-10-02 办公教程 101
Redis持久化
Redis的数据是存储在内存的,当程序崩溃或者服务器宕机,那么内存里的数据就会丢失。所以避免数据丢失的情况,需要将数据保存到其他的存储设备中。
Redis提供两种方式来持久化,分别是
-
RDB(Redis Database):记录某个时刻的全部数据,本质是存储二进制数据的快照到磁盘,后续通过加载RDB文件恢复数据
-
AOF(Append Only File):记录执行的每条命令,通过重新执行命令来恢复数据。本质是记录操作日志,后续通过日志恢复数据。
RDB
本质
记录某个时刻的全部数据,本质是:将某一时刻Redis服务器内存中的数据保存到磁盘中的二进制文件中(dump.rdb),后续通过加载RDB文件恢复数据。
RDB触发(执行持久化)
RDB的触发包括手动触发,自动触发,关闭时持久化
-
手动触发包括主动执行sava命令,主动执行bgsave命令:
-
save命令:会在redis主线程执行持久化操作,会阻塞主线程,只有RDB持久化完成,才能响应客户端的请求,所以在生产模式的时候慎用(不用)。Redis在正常关闭时,会执行save命令来持久化数据
-
bgsave命令:background save,即后台保存。Redis会创建一个子进程来生成快照文件,创建子进程可能会有短暂的阻塞,而父进程(Redis的服务器进程)会继续处理客户端的请求。一般用的是这个命令
-
自动触发:
用户可以在Redis的配置文件中进行设置(默认开启),Redis会根据设置自动调用bgsave。比如,
#save <seconds> <changes>
save 900 1 表示每900秒内,有1条写数据操作,则触发bgsave
save 300 10 多条命令是并集关系,如果满足其中一个就会触发
RDB执行流程
Redis官网描述:
How it works Whenever Redis needs to dump the dataset to disk, this is what happens: 1.Redis forks. We now have a child and a parent process. 2.The child starts to write the dataset to a temporary RDB file. 3.When the child is done writing the new RDB file, it replaces the old one. This method allows Redis to benefit from copy-on-write semantics.
-
Redis fork出一个子进程
-
子进程把数据写入临时的RDB文件
-
写完之,新RDB文件替换旧RDB文件
最后还有一句话:这种方式让Redis从”写时复制“技术收益。也就是,Redis在执行持久化的时候,依然可以处理客户端的命令,数据是可以被修改的。
具体来讲,fork创建子进程后,子进程会复制父进程的页表,页表指向的物理地址是同一个,所以子进程和父进程时共享同一片数据的。当父进程处理客户端请求,发生内存数据修改时,物理内存才会被复制一份给子进程,所以子进程的持久化操作是不会被影响。
AOF
记录执行的每条命令,通过执行命令来恢复数据。本质是记录操作日志,后续通过日志恢复数据。
AOF日志文件其实就是普通的文本,可以通过cat命令查看里面的内容。
Redis先执行写操作命令后,再将该命令记录到AOF日志中。有以下几点好处:
-
避免额外的检查开销。如果命令的语法有问题又不进行检查,直接先记录到AOF日志里,等到Redis使用日志文件恢复数据的时候,就会出错。所以先执行命令后,只有命令执行成功才记录到AOF日志中,就能避免额外的检查开销,保证AOF日志里的命令是正确的。
-
不会阻塞当前操作命令的执行。
当然也存在一定风险:
-
执行写操作和记录AOF日志是两个过程,当Redis还没有来得及将命令写入硬盘时,服务器宕机,数据就有丢失的风险
-
会阻塞下一个操作命令的执行。
因为执行命令和记录AOF日志都是在主进程完成的
开启AOF
打开redis配置文件
appendonly no # The name of the append only file (default: "appendonly.aof") appendfilename "appendonly.aof"
默认AOF是关闭的,通过设置appendonly为yes可开启
AOF写入流程
-
将数据写入AOF缓冲区中,这个缓冲区叫aof_buf,是一个sds数据
-
将aof_buf的数据写入AOF文件,此时还没有写入硬盘,而是拷贝到内核缓冲区page cache中。一共有4个时机,会调用一个flushAppendOnlyFile的函数,这个函数会使用write函数来将数据写入操作系统缓冲区
-
处理完事件后,等待下一次事件之前,也就是beforeSleep中
-
周期函数serverCron中
-
服务器退出之前的准备工作时
-
通过配置指令关闭AOF功能时
内核缓冲区page cache:是操作系统内核中用于缓存磁盘数据的一部分内存区域
硬盘缓冲区:是硬盘或磁盘控制器中的硬件缓存
-
-
将内核缓冲区的数据写入磁盘。即调用系统的flush函数,刷盘其实还是在flushAppendOnlyFile函数中,但是不一定调用了flushApeendOnlyFile,flush就一定会被调用。这里支持了刷盘时机的配置。
/* Perform the fsync if needed. */ if (server.aof_fsync == AOF_FSYNC_ALWAYS) { /* redis_fsync is defined as fdatasync() for Linux in order to avoid * flushing metadata. */ latencyStartMonitor(latency); redis_fsync(server.aof_fd); /* Let's try to get this data on the disk */ latencyEndMonitor(latency); latencyAddSampleIfNeeded("aof-fsync-always",latency); server.aof_last_fsync = server.unixtime; } else if ((server.aof_fsync == AOF_FSYNC_EVERYSEC && server.unixtime > server.aof_last_fsync)) { if (!sync_in_progress) aof_background_fsync(server.aof_fd); server.aof_last_fsync = server.unixtime; }
注意:
-
为什么先将数据写入aof缓冲中,而不直接同步到磁盘呢?
因为实时写入磁盘会带来很高的磁盘IO,影响性能
AOF写入策略(AOF日志写入磁盘时机)
Redis提供了三种写入策略,决定了AOF日志什么时候写入磁盘,包括
-
appendfsync always:每次写操作命令执行完之后,同步将AOF日志数据写入磁盘。
-
appendfsync everysec:每次写操作命令执行完之后,先将命令写入到AOF文件的内核缓冲区,然后每隔一秒将缓冲区里的内容写入磁盘
-
appendfsync no:Redis不去控制写入硬盘的时机,由操作系统控制。每次先将命令写入AOF文件的内核缓冲区,再由操作系统决定何时写入硬盘。一般情况linux会每30秒刷一次盘。这种策略对性能的影响最小,但发生崩溃时会丢失较多数据。
Redis的默认设置是每秒钟同步一次数据到磁盘,提供较好的性能和数据可靠性。也需要根据实际业务来选择,比如只是简单的缓存,不存在热点缓存,就可以30秒同步一次数据到磁盘中。Always策略每次执行写操作就同步将AOF日志写入硬盘,影响主进程的性能。
根据业务场景进行选择:
-
如果要高性能,就选No策略
-
如果要高可靠,就选Always策略
-
如果折中,较好的性能和可靠性,就选Everysec策略
AOF重写
随着命令越来越多,AOF文件会越来越大,不仅占用大量磁盘空间,而且恢复数据也会变慢。
在AOF文件中,有些命令是没有作用的,比如一开始set一个数据为10,后来又set为100,那么前面set为10就没有作用了,完全可以把前面set为10的命令去掉。
所以,AOF重写机制的妙处在于,尽管某个键值对被多条命令重复修改,最终也只需用一条命令去记录这个键值对当前的最新状态,进而减少AOF日志中的命令数量。
AOF重写流程
写入AOF日志的操作是在主进程完成的,因为它写入的内容不多,所以不太影响命令的操作。
而AOF重写时,需要读取所有缓存的键值对数据,为每一个键值对生成一条命令,然后写入到新的AOF文件,重写完后,将旧AOF文件替换掉。所以AOF过程由后台子进程来完成,避免阻塞主进程。
这里使用子进程而不是线程,因为如果是使用线程,多线程之间会共享内存,那么在修改共享内存数据的时候,需要通过加锁来保证数据的安全,而这样就会降低性能。而使用子进程,创建子进程时,父子进程是共享内存数据的,不过这个共享的内存只能以只读的方式,而当父子进程任意一方修改了该共享内存,就会发生「写时复制」,于是父子进程就有了独立的数据副本,就不用加锁来保证数据安全。
-
重写时,主进程会fork出一个子进程,由子进程将这些Redis数据写入重写日志
-
在子进程进行重写期间,主进程也会将新的写操作写入到AOF重写缓冲区中
-
当新的AOF文件创建完毕,Redis就会将重写缓冲区的内容追加到新的AOF文件,新AOF文件替换旧AOF文件
所以,尽管重写过程中有新数据写入,通过追加AOF重写缓冲的方式到新文件,依然可以保证不会丢失最新的写入操作
AOF混合持久化
是什么
混合持久化发生在原有的AOF流程。开启了混合持久化,在AOF重写日志的时候,fork出来的子进程会将内存数据以RDB的方式写入新的AOF文件中,期间主进程将写操作命令写入重写缓冲区中,最后追加到新的AOF文件中。
此时的AOF文件前半部分是RDB格式的全量数据,后半部分是AOF格式的增量数据。
优势
既有RDB文件小,加载快的优势,也有AOF持久化数据损失少的优势。但因为含有二进制数据,可读性会差一些。
服务启动时如何加载数据
混合持久文件里有REDIS这个标记,加载时能通过这个标记进行判断是否开启了混合持久化。
可以通过配置文件开启,5.0之后默认是打开的,所以5.0之后只要AOF配置开启,默认就是混合持久化。
更多 推荐PPT模板
-
一份简洁大气的商务风格工作总结汇报PPT模板,浅灰色背景,蓝色主色调,包括过渡页、时间轴、折线图、地图等页面。
2023-06-14 765
-
灰格子背景 简洁蓝商务PowerPoint幻灯片模板
2023-06-15 752
-
不忘初心 牢记使命——蓝金党政风工作汇报ppt模板
2023-06-15 743
-
彩虹多彩王国ppt模板
2023-06-15 739
相关推荐
- 10-06 K8sGPT,基于 AI 的云原生终极工具
- 10-06 【Java】复制数组的四种方式
- 10-06 Qt::图层框架-图片图层-序列图层-QGraphicsPixmapItem
- 10-06 一篇博客学会系列(1) —— C语言中所有字符串函数以及内存函数的使用和注意事项
- 10-06 美丽的图论
- 10-06 Pygame实现黑客帝国屏幕效果
- 10-06 后台管理系统: 商品管理
- 10-06 chrome插件-入门
- 10-06 【C++入门到精通】C++入门 —— set & multiset (STL)
- 10-02 【数据结构】什么是数据结构?
- 最近发表
-
- 一份有创意的大学生求职个人简历PPT模板,时尚全图背景配合大号字体,共32页,内容非常详尽,好看的动态效果。使用字体:汉仪菱心体简。
- 一份精美时尚的商务风格多功能幻灯片模板,以城市楼群远景图片为背景,全图型设计,时尚大气,共18页,目录页、过渡页、时间轴、图文说明等各类页面齐全丰富,可用于商务
- 小清新复古色系通用PPT模板。一份小清新风格的幻灯片模板,采用养眼柔和的复古色系艺术抽象条纹设计,通用性强。
- 实用精品商业计划书PPT模板。一份精美实用的商业计划策划书PPT模板,框架完整,内容实用,严谨专业,页面丰富。
- 炫酷欧美复古杂志风PPT模板。一份创意精美幻灯片模板,采用复古色系配合杂点做旧效果,很有质感,杂志风格的排版布局,无缝滚动切换效果,适合用于新年展望、员工激励等
- 一份实用的项目合作方案汇报PPT模板,排版布局配色简洁大气专业,包括项目介绍、需求分析、项目设计、各方需要配合的工作、项目预算几个部分。
- 好看的半透明效果PPT模板。一份很好看的幻灯片模板,采用时尚的半透明效果设计,大气山峰雪山背景,动态演示。
- 一份精美的简约的半透明IOS苹果风格PPT模板,渐变模糊光晕背景,半透明图形元素,好看的动态播放效果,用途广泛。
- 黑黄配色时尚欧美风PPT模板。一份精美好看的幻灯片模板,黑黄大气经典配色,时尚欧美范,共19页,页面丰富实用。
- 杂志风项目策划汇报PPT模板。经典红黑配色,干净利落的大气商务风格,动态演示,适合项目策划报告汇报使用。
- 标签列表
- 控制面板
- 搜索