文章目录

  • 一. 概述redis持久化的俩种模式
  • 二. rdb持久化模式
    • 1.rdb持久化核心思路
    • 2.rdb持久化难点
    • 3.rdb持久化后rdb文件的格式
    • 4.rdb持久化触发条件
    • 5.rdb持久化数据安全性
    • 6.rdb持久化核心源码(bgsave为例)
  • 三. aof持久化模式
    • 1.aof持久化核心思路
    • 2.aof持久化难点
    • 3.aof持久化文件格式
    • 4.aof持久化触发条件
    • 5.aof持久化对redis性能影响
    • 6.aof文件重写
    • 7.aof持久化的安全性
  • 四. rdb持久化在恢复过程中会比aof快很多么?
  • 五. 总结

一. 概述redis持久化的俩种模式

随着redis越来越流行,使用者不在仅仅满足其只是一个内存数据库,同时也期望其能将内存数据落磁盘,这样重启服务就不会导致缓存数据丢失了

redis持久化有俩种模式模式,分别如下:

持久化模式 说明 优点 缺点
rdb模式 定期将redis当前内存数据快照备份到硬盘 redis重启时恢复速度快 由于备份不宜频繁,会导致系统异常宕机时,redis大量数据丢失
aof模式 将redis执行的命令每隔1s批量同步到文件中 机器异常宕机时,最多丢失1s数据 由于保存的是命令,会导致保存很多赘余数据,文件过大(这时候恢复起来相对rdb会慢很多)

二. rdb持久化模式

1.rdb持久化核心思路

获取当前内存快照并将快照数据保存到磁盘实现当前数据全量备份

2.rdb持久化难点

(1)如何获取当前内存数据快照
redis利用linux fork子进程后( cow机制:https://juejin.im/post/5bd96bcaf265da396b72f855 )子进程拥有父进程的内存快照来获取内存快照
(2)保存数据落盘时io操作阻塞其他请求
redis rdb持久化落盘操作只在独立的子进程中进行不会影响到主进程中的其他请求

3.rdb持久化后rdb文件的格式

(1)redis rdb文件整体格式如图1所示

  • 开头为固定的REDIS 5个字符,标示这是一个redis rdb文件
  • 5.0.0标示保存改rdb文件的redis服务为5.0.0版本
  • 64标示保存rdb文件的redis所在机器为64位机
  • 1554103539为该rdb文件的创建时间
  • 23343563为该rdb内存快照需占用内存大小
  • 接着保存的为复制相关标示和数据库数据(见图2)
  • EOF标志代表rdb文件结尾
  • 63562735845846756为rdb完整性检查的校验和

(2)redis database在rdb文件中的整体格式如图2所示

  • SELECTDB代表一个数据库的开始标志
  • 0代表数据库编号,标示接下来保存的为0号数据库的内容
  • 3456为当前数据库的总元素个数
  • 24为当前数据库过期元素个数
  • KeyValuePair保存具体的数据库中k-v的值

4.rdb持久化触发条件

(1)rdb持久化为redis开启的默认持久化方式,可通过配置文件灵活配置,默认如下

save 900 1          //15分钟内有一条数据写入时触发rdb持久化
save 300 10        //5分钟内有10条数据写入时触发rdb持久化
save 60 10000     //1分钟内有10000条数据写入时触发rdb持久化

(2)除了默认触发之外,我们也可以通过redis客户端发送命令主动触发rdb持久化,具体命令如下:

>save          //主进程执行rdb持久化操作
>bgsave      //生成后台进程执行rdb持久化(默认方式)

5.rdb持久化数据安全性

疑问: rdb持久化模式下,当机器宕机,会丢失多少数据?
答: 从最近一次rdb保存到宕机时的数据都会丢失

6.rdb持久化核心源码(bgsave为例)

int rdbSaveBackground(char *filename, rdbSaveInfo *rsi) {pid_t childpid;long long start;//如果已经存在aof重写进程或rdb持久化进程则返回错误if (server.aof_child_pid != -1 || server.rdb_child_pid != -1) return C_ERR;server.dirty_before_bgsave = server.dirty;server.lastbgsave_try = time(NULL);//打开与子进程的进程间通信管道(用于子进程完成持久化后给父进程发送消息)openChildInfoPipe();start = ustime();if ((childpid = fork()) == 0) {int retval;//子进程//关闭监听的连接closeListeningSockets(0);   //设置子进程名字redisSetProcTitle("redis-rdb-bgsave");  //保存全量内存信息retval = rdbSave(filename,rsi);        if (retval == C_OK) {//发送cow内存大小信息给父进程sendChildInfo(CHILD_INFO_TYPE_RDB);   }//退出rdb持久化对应进程exitFromChild((retval == C_OK) ? 0 : 1);} else {//父进程//统计fork进程花费的时间,当redis占用过多内存空间fork进程可能会很慢server.stat_fork_time = ustime()-start;server.stat_fork_rate = (double) zmalloc_used_memory() * 1000000 / server.stat_fork_time / (1024*1024*1024); /* GB per second. */server.rdb_save_time_start = time(NULL);server.rdb_child_pid = childpid;server.rdb_child_type = RDB_CHILD_TYPE_DISK;//重新设置dict是否可以执行resize操作标志updateDictResizePolicy();return C_OK;}return C_OK;
}

三. aof持久化模式

1.aof持久化核心思路

将服务器收到的更新命令直接写入文件尾部,恢复时直接重放文件中命令即可

2.aof持久化难点

(1)aof文件由于赘余数据,会变得很庞大(占用磁盘空间、重启load数据变慢)
redis会定期重写aof文件(下文中会详细介绍),抛弃赘余
(2)保存数据到aof文件落盘时io操作阻塞其他请求
redis aof文件写入在主线程,比较耗时的刷盘操作(fsync)则由专门的异步线程来处理,保证主线程不被io阻塞

3.aof持久化文件格式

aof持久化直接将redis命令协议写入,如图3所示

4.aof持久化触发条件

redis默认不开启aof持久化方式,可通过修改如下配置开启

appendonly yes #yes开启no关闭

aof持久化刷盘频率控制

# appendfsync always  //每次命令都刷盘
appendfsync everysec //每秒刷盘一次(默认)
# appendfsync no  //从不刷盘,由内核去刷盘

5.aof持久化对redis性能影响

疑问: aof持久化涉及磁盘io操作(write数据到aof文件),那么该操作是否会严重影响redis吞吐量?
答: 在aof文件追加过程中,write调用是在redis主线程内,而fsync(将文件数据从内核缓存区buffer中真正写入磁盘)控制刷盘却是在一个独立的后台线程中来完成,所以并不需要担心开启aof会十分影响redis性能

6.aof文件重写

(1)aof重写解决的问题
aof文件重写是为了解决aof命令添加持久化模式下,会有大量赘余命令(比如设置一个k-v,之后又删除)导致aof文件过大。不仅浪费系统资源(主要是磁盘),而且会导致load数据到内存重放变慢
(2)aof重写核心原理
aof重写过程会有大量io操作,所以redis会像写rdb文件一样为其分配一个独立的进程去执行重写。重写的过程中redis会将新完成的命令写入一段临时buf。当aof重写完成,将buf中的命令数据批量写入aof文件中

我们知道aof重写是去掉赘余命令(例如先增加后删除),如果通过原文件内容去逐一进行逻辑计算找出赘余必然会耗费大量计算和存储资源。redis是通过直接将当前内存k-v数据拼装成命令协议格式并写入aof文件,如此便十分优雅的去掉原aof文件中的赘余命令

(3)aof重写客户端触发命令:

>bgrewriteaofCommand

7.aof持久化的安全性

疑问: aof持久化模式下,机器宕机,最多丢失多少数据
答:aof根据appendfsync配置的不同,丢失数据情况分别如下:

| 模式 | 说明 | 数据安全级别 |最大丢失数据
| ------------ | ------------ |----
|always|每次写入都刷盘|高|宕机过程中那次epoll事件循环中的已完成命令的更新数据
|everysec|每s刷盘一次|中|最多丢失2s数据
|no|从不刷盘,刷盘工作完全交于操作系统来完成|低|无法准确评估|

  • 对于always参数,由于刷盘并不是每次更新命令都执行一次,而是一次epollwait触发后只批量执行一次。故其也会丢失数据
  • everysec虽然是每s执行一次刷盘,理论上最大丢失1s数据,但是由于在刷盘过程中有个特殊逻辑,当某次刷盘前,判断刷盘线程已在工作(处理之前的刷盘任务),则本次刷盘延后2s。故该模式下最大丢失其实是2s的数据量
  • no啥时候刷盘,完全有内核管理,对应用系统来说存在很大的不确定性,故很难评估其数据安全性

四. rdb持久化在恢复过程中会比aof快很多么?

网上各种资料显示,rdb在恢复过程中会优于aof文件。事实也的确如此,因为aof文件中会存在大量赘余命令,当然会恢复的慢。但是不要忘了,aof文件可是会定期重写(刚重写后同样没赘余)的,如果是刚重写后不久的aof文件,那么其恢复就不会相对rdb慢很多了(理论分析)。所以可以说只要我们重写aof的频次不低,那么aof恢复就不怕他相较rdb有明显的速度差异

五. 总结

通过全文对rdb和aof持久化的详细说明,相信你在工程上能根据实际业务场景选择出最合适的持久化方式了,这也是作者写本文的初衷。

细说redis持久化流程相关推荐

  1. 深入学习Redis持久化

    一.Redis高可用概述 在介绍Redis高可用之前,先说明一下在Redis的语境中高可用的含义. 我们知道,在web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常 ...

  2. 学习Redis持久化

    Redis支持RDB和AOF两种持久化机制,持久化功能有效地避免因进程退出造成的数据丢失问题,当下次重启时利用之前持久化的文件即可实现数据恢复.理解掌握持久化机制对于Redis运维非常重要. 首先介绍 ...

  3. [Redis]Redis章2 Redis 持久化

    一.Redis持久化是如何工作的?  什么是持久化?简单来讲就是将数据放到断电后数据不会丢失的设备中,也就是我们通常理解的硬盘上. 首先我们来看一下数据库在进行写操作时到底做了哪些事,主要有下面五个过 ...

  4. 二十二、redis持久化之AOF

    AOF(Append Only File) redis是一个内存数据库,数据保存在内存中,但是我们都知道内存的数据变化是很快的,也容易发生丢失.幸好Redis还为我们提供了持久化的机制,分别是RDB( ...

  5. 二十一、redis持久化之RDB

    RDB(Redis DataBase) redis是一个内存数据库,数据保存在内存中,但是我们都知道内存的数据变化是很快的,也容易发生丢失.幸好Redis还为我们提供了持久化的机制,分别是RDB(Re ...

  6. redis(7)、redis持久化

    2019独角兽企业重金招聘Python工程师标准>>> redis持久化,顾名思义,就是把内存中的数据保存到硬盘上,以防redis发生意外造成数据丢失. 目前有两种方案,RDB方式和 ...

  7. 细说Redis监控和告警

    https://blog.csdn.net/qq_27623337/article/details/53206685 对于任何应用服务和组件,都需要一套完善可靠谱监控方案. 尤其redis这类敏感的纯 ...

  8. 解密Redis持久化

    本文内容来源于Redis作者博文,Redis作者说,他看到的所有针对Redis的讨论中,对Redis持久化的误解是最大的,于是他写了一篇长文来对Redis的持久化进行了系统性的论述.文章非常长,也很值 ...

  9. php使用redis持久化,Redis持久化完整版本

    持久化的简介 RDB AOF RDB与AOF的区别 持久化应用场景 对于持久化这个功能点,其实很简单没有那么复杂 演示环境 centos7.0 redis4.0 redis存放目录:/usr/loca ...

最新文章

  1. 1067. 试密码(20)
  2. 成功解决but is 0 and 2 (computed from start 0 and end 9223372 over shape with rank 2 and stride-1)
  3. 算法和编程面试题精选 TOP50!(附代码+解题思路+答案)
  4. CF9D-How many trees?【dp】
  5. 小白来学C语言之宏定义(#define)
  6. LeetCode-计数质数
  7. WinISO镜像文件使用简介
  8. android netcfg命令,Android netcfg
  9. EIDROS3.9学习(一)
  10. 辛意云教授讲《论语》
  11. 记一次生产事故排查——CPU高负载原因排查分析
  12. Vue 设置图片不转为base64
  13. ISCC2021 wp
  14. jmeter 压力测试各种值的意思
  15. BorderStyle short usage
  16. linux aria进程,Linux安装 Aria2
  17. 关于用同一个Form写编辑和添加的VUE报错
  18. python 全栈开发,Day84(django请求生命周期,FBV和CBV,ORM拾遗,Git)
  19. windows网络服务进程管理dos命令
  20. 大型分布式电商系统架构是如何从0开始演进

热门文章

  1. Java操作Redis存储对象类型数据
  2. CoOS使用教程——消息队列
  3. 选购笔记本电脑的三招半式
  4. 网安笔记15 入侵检测IDS
  5. 牛客网SQL大厂真题二刷小白白话总结(五)某宝店铺分析(电商模式)
  6. 四维超体运动在三维空间的表现(使用three.js)
  7. android studio 隐藏显示,Android Studio 隐藏和显示键盘
  8. Maya的一些实用插件——记录分享篇
  9. “区块”和“链”的火花,区块链到底为何物
  10. 邮箱大师发送邮件服务器连接失败,网易邮箱大师退信的解决方法分享 网易邮箱大师发不了邮件的解决方法介绍...