Redis设计与实现2.2:数据持久化
数据持久化
这是《Redis设计与实现》系列的文章,系列导航:Redis设计与实现笔记
RDB持久化
RDB 持久化功能所生成的 RDB 文件是一个经过压缩的二进制文件,通过该文件可以还原生成 RDB 文件时的数据库状态。
基本使用

另外,由于AOF文件更新更频繁,所以:
优先使用AOF进行还原
只有AOF关闭时才会进行RDB备份
BGSAVE 虽然是非阻塞的,但是在进行时会拒绝掉 SAVE、BGSAVE命令,BGREWRITEAOF 会被推迟到执行完再执行。
而如果 BGREWRITEAOF 正在执行,则 BGSAVE 会被拒绝。
自动保存功能
设置
save 900 1
save 300 10
只要满足如下条件的一个,BGSAVE就会被执行:
- 900s内,对数据库至少进行了1次修改
- 300s内,对数据库至少进行了10次修改
原理
上述的配置信息保存的结构如下图所示:1

另外,程序还需要记录对应这两个配置在数据库中对应的信息:
- dirty计数器:记录距离上一次成功执行 SAVE 命令或者 BGSAVE 命令之后,服务器对数据库状态进行了多少次修改
- lastsave:记录上一次成功执行备份的UNIX时间戳
Redis服务器周期性操作函数 serverCron 默认每 100 毫秒执行一次,用于对正在运行的服务器进行维护,其中一项工作就是检查 save 选项保存的条件是否满足。
RDB文件结构

这里只给出了一个简单的关系图,如果想要了解具体的内容请阅读原书。
AOF持久化
AOF 持久化是通过保存 Redis 服务器所执行的写命令来记录数据库的状态的。
写入AOF的步骤
三步骤:
- 命令追加:服务器执行完一个写命令后,会追加到服务器状态的
aof_buf缓冲区的末尾 - 文件写入:serverCron 函数在定时运行的时候会调用
flushAppendOnlyFile函数,考虑是否将上述缓冲区的内容写入和保存到 AOF 文件中 - 文件同步
写入和同步:
为了提高文件的写入效率,在现代操作系统中,当用户调用 write 函数时会先将数据保存在一个内存缓冲区里,等超过一定的时限或空间被填满再写入磁盘。
这样虽然提高了效率,但是可能会影响安全性。
为此,系统提供了
fsync和fdatasync可以强制让操作系统立刻同步到硬盘中。
appendfsync 参数配置:
- always:总是写入并同步
- everysec:每秒进行写入并同步
- no:写入但不同步
载入AOF的步骤
(很直观的步骤)
- 创建一个不带网络连接的伪客户端
- 从AOF文件中分析并读取一条写命令
- 使用伪客户端执行该命令
- 重复上述步骤,直到所有命令完成
AOF 重写
为什么?
由于 AOF 时通过保存被执行的写命令来记录数据库状态的,所以随着服务器运行时间的流逝,AOF 文件的内容会越来越多,文件体积也会越来越大,需要加以控制,以免对 Redis 服务器、甚至整个宿主机造成影响。
怎么做?
BGREWRITEAOF 命令进行 AOF 重写。
重写的实现?
最简单的方法是通过分析 Redis 中的数据,然后生成相应的插入指令,而不是通过分析之前的命令来判断哪些可以被跳过。
后台重写
为了在重写过程中也能处理请求,可以采用后台重写的方式。当然在重写的过程中数据也可能发生变化,所以要设置一个 AOF 重写缓冲区。(类似主从复制时的操作)

当子进程完成 AOF 重写工作后,他会向父进程发送一个信号,父进程在接到该信号之后,就会调用一个信号处理函数(阻塞),并执行如下工作:
- 将 AOF 重写缓冲区的内容写入到新的 AOF 文件中
- 对新的 AOF 文件进行改名,原子地覆盖现有的 AOF 文件
Redis设计与实现2.2:数据持久化的更多相关文章
- redis启动加载过程、数据持久化
背景 公司一年的部分业务数据放在redis服务器上,但数据量比较大,单纯的string类型数据一年就将近32G,而且是经过压缩后的. 所以我在想能否通过获取string数据的时间改为保存list数据类 ...
- Redis 设计与实现 (三)--持久化
RDB 持久化 一.生成RDB cmd:SAVE --阻塞进程,执行完,才能有效接收客户端命令. cmd: BGSAVE --非阻塞,开启子进程保存. 客户端如果发送SAVE和BGSAVE命令直 ...
- 【笔记】《Redis设计与实现》chapter10 RDB持久化
chapter10 RDB持久化 10.1 RDB文件的创建和载入 有两个Redis命令可以用于生成RDB文件,SAVE和BGSAVE SAVE阻塞服务器进程进行RDB文件的创建,BGSAVE则创建服 ...
- 【笔记】《Redis设计与实现》chapter11 AOF持久化
11.1 AOF持久化的实现 命令追加 当AOF持久化处于开启状态时,服务器执行完一个写命令之后,会以协议格式将被执行的写明了追加到服务器状态的aof_buf缓冲区 struct redisServe ...
- redis 配置文件 append only file(aof)部分---数据持久化
############################## 仅追加方式 ############################### #默认情况下Redis会异步的将数据导出到磁盘上.这种模式对许 ...
- Redis学习笔记(5)——Redis数据持久化
出处http://www.cnblogs.com/xiaoxi/p/7065328.html 一.概述 Redis的强大性能很大程度上都是因为所有数据都是存储在内存中的,然而当Redis重启后,所有存 ...
- redis学习——数据持久化
一.概述 Redis的强大性能很大程度上都是因为所有数据都是存储在内存中的,然而当Redis重启后,所有存储在内存中的数据将会丢失,在很多情况下是无法容忍这样的事情的.所以,我们需要将内存中的数据持久 ...
- redis学习(九)——数据持久化
一.概述 Redis的强大性能很大程度上都是因为所有数据都是存储在内存中的,然而当Redis重启后,所有存储在内存中的数据将会丢失,在很多情况下是无法容忍这样的事情的.所以,我们需要将内存中的数据持久 ...
- Redis 中的数据持久化策略(AOF)
上一篇文章,我们讲的是 Redis 的一种基于内存快照的持久化存储策略 RDB,本质上他就是让 redis fork 出一个子进程遍历我们所有数据库中的字典,进行磁盘文件的写入. 但其实这种方式是有缺 ...
- 探索Redis设计与实现11:使用快照和AOF将Redis数据持久化到硬盘中
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
随机推荐
- Leetcode26——删除有序数组中的重复项(双指针法)
Leetcode26--删除有序数组中的重复项(双指针法) 1. 题目简述 给你一个升序排列的数组 nums ,请你原地 删除重复出现的元素,使每个元素只出现一次 ,返回删除后数组的新长度.元素的相对 ...
- servlet中的HttpServletRequest对象
HttpServletRequest对象表示客户端浏览器发起的请求,当客户端浏览器通过HTTP协议访问服务器时,Tomcat会将HTTP请求中的所有信息解析并封装在HttpServletRequest ...
- python学习笔记(十)——进程间通信
python 在进程间通信时有很多方式,比如使用Queue的消息队列,使用 pip的管道通信,share memory 共享内存或 semaphore 信号量等通信方式. 这里我们演示一下通过消息队列 ...
- 前端进阶(8) - 前端开发需要了解的工具集合:webpack, eslint, prettier, ...
前端开发需要了解的工具集合:webpack, eslint, prettier, ... 前端开发需要了解的一些工具,这些工具能够帮助你在项目开发中事半功倍. 1. nrm: npm registry ...
- python大佬养成计划----flask_bootstrap装饰网页
flask_bootstrap Bootstrap 是 Twitter 开发的一个开源框架,它提供的用户界面组件可用于创建整洁且具有吸引力的网页,而且这些网页还能兼容所有现代 Web 浏览器. Boo ...
- Python爬虫报错:"HTTP Error 403: Forbidden"
错误原因:主要是由于该网站禁止爬虫导致的,可以在请求加上头信息,伪装成浏览器访问User-Agent. 新增user-agent信息: headers = {'User-Agent':'Mozilla ...
- response.setHeader("Cache-Control","no-cache");的作用
1. response.setHeader("Cache-Control","no-cache"); This is used to prevent the ...
- LINUX执行shutdown.sh提示:-bash: ./startup.sh: Permission denied
在执行./startup.sh,或者./shutdown.sh的时候,爆出了Permission denied, 其实很简单,就是今天在执行tomcat的时候,用户没有权限,而导致无法执行, 用命令c ...
- 使用cookie/session实现简单的用户信息的保存
cookie一般用来存储非关键信息 , 用户名和密码等敏感信息一般采用session 来存储:cookie和session的最大区别是当服务器端存储session 之后,用户再次请求时候只是请求了一个 ...
- 文档声明(Doctype)和<!Doctype html>有何作用? 严格模式与混杂模式如何区分?它们有何意义?
文档声明的作用: 文档声明是为了告诉浏览器,当前HTML文档使用什么版本的HTML来写的,这样浏览器才能按照声明的版本来正确的解析. <!doctype html> 的作用就是让浏览器进入 ...