数据持久化

这是《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的步骤

三步骤:

  1. 命令追加:服务器执行完一个写命令后,会追加到服务器状态的 aof_buf 缓冲区的末尾
  2. 文件写入:serverCron 函数在定时运行的时候会调用 flushAppendOnlyFile 函数,考虑是否将上述缓冲区的内容写入和保存到 AOF 文件中
  3. 文件同步

写入和同步:

为了提高文件的写入效率,在现代操作系统中,当用户调用 write 函数时会先将数据保存在一个内存缓冲区里,等超过一定的时限或空间被填满再写入磁盘。

这样虽然提高了效率,但是可能会影响安全性。

为此,系统提供了 fsyncfdatasync 可以强制让操作系统立刻同步到硬盘中。

appendfsync 参数配置:

  1. always:总是写入并同步
  2. everysec:每秒进行写入并同步
  3. no:写入但不同步

载入AOF的步骤

(很直观的步骤)

  1. 创建一个不带网络连接的伪客户端
  2. 从AOF文件中分析并读取一条写命令
  3. 使用伪客户端执行该命令
  4. 重复上述步骤,直到所有命令完成

AOF 重写

为什么?

由于 AOF 时通过保存被执行的写命令来记录数据库状态的,所以随着服务器运行时间的流逝,AOF 文件的内容会越来越多,文件体积也会越来越大,需要加以控制,以免对 Redis 服务器、甚至整个宿主机造成影响。

怎么做?

BGREWRITEAOF 命令进行 AOF 重写。

重写的实现?

最简单的方法是通过分析 Redis 中的数据,然后生成相应的插入指令,而不是通过分析之前的命令来判断哪些可以被跳过。

后台重写

为了在重写过程中也能处理请求,可以采用后台重写的方式。当然在重写的过程中数据也可能发生变化,所以要设置一个 AOF 重写缓冲区。(类似主从复制时的操作)

当子进程完成 AOF 重写工作后,他会向父进程发送一个信号,父进程在接到该信号之后,就会调用一个信号处理函数(阻塞),并执行如下工作:

  1. 将 AOF 重写缓冲区的内容写入到新的 AOF 文件中
  2. 对新的 AOF 文件进行改名,原子地覆盖现有的 AOF 文件

Redis设计与实现2.2:数据持久化的更多相关文章

  1. redis启动加载过程、数据持久化

    背景 公司一年的部分业务数据放在redis服务器上,但数据量比较大,单纯的string类型数据一年就将近32G,而且是经过压缩后的. 所以我在想能否通过获取string数据的时间改为保存list数据类 ...

  2. Redis 设计与实现 (三)--持久化

    RDB 持久化 一.生成RDB cmd:SAVE  --阻塞进程,执行完,才能有效接收客户端命令. cmd:  BGSAVE  --非阻塞,开启子进程保存. 客户端如果发送SAVE和BGSAVE命令直 ...

  3. 【笔记】《Redis设计与实现》chapter10 RDB持久化

    chapter10 RDB持久化 10.1 RDB文件的创建和载入 有两个Redis命令可以用于生成RDB文件,SAVE和BGSAVE SAVE阻塞服务器进程进行RDB文件的创建,BGSAVE则创建服 ...

  4. 【笔记】《Redis设计与实现》chapter11 AOF持久化

    11.1 AOF持久化的实现 命令追加 当AOF持久化处于开启状态时,服务器执行完一个写命令之后,会以协议格式将被执行的写明了追加到服务器状态的aof_buf缓冲区 struct redisServe ...

  5. redis 配置文件 append only file(aof)部分---数据持久化

    ############################## 仅追加方式 ############################### #默认情况下Redis会异步的将数据导出到磁盘上.这种模式对许 ...

  6. Redis学习笔记(5)——Redis数据持久化

    出处http://www.cnblogs.com/xiaoxi/p/7065328.html 一.概述 Redis的强大性能很大程度上都是因为所有数据都是存储在内存中的,然而当Redis重启后,所有存 ...

  7. redis学习——数据持久化

    一.概述 Redis的强大性能很大程度上都是因为所有数据都是存储在内存中的,然而当Redis重启后,所有存储在内存中的数据将会丢失,在很多情况下是无法容忍这样的事情的.所以,我们需要将内存中的数据持久 ...

  8. redis学习(九)——数据持久化

    一.概述 Redis的强大性能很大程度上都是因为所有数据都是存储在内存中的,然而当Redis重启后,所有存储在内存中的数据将会丢失,在很多情况下是无法容忍这样的事情的.所以,我们需要将内存中的数据持久 ...

  9. Redis 中的数据持久化策略(AOF)

    上一篇文章,我们讲的是 Redis 的一种基于内存快照的持久化存储策略 RDB,本质上他就是让 redis fork 出一个子进程遍历我们所有数据库中的字典,进行磁盘文件的写入. 但其实这种方式是有缺 ...

  10. 探索Redis设计与实现11:使用快照和AOF将Redis数据持久化到硬盘中

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

随机推荐

  1. js技术之拖动table标签

    一.js技术之拖动table标签 起因:前几天公司,突然安排一个任务 任务描述:要求尺码table列表要像Excel表中一样可以直接移动整行尺码到任意行位置 技术点:采用ui的sortable技术来h ...

  2. 定常系统(时不变系统)和时变系统&& 动态系统和静态系统

    根据系统是否含有参数随时间变化的元件,自动控制系统可分为时变系统与定常系统两大类. 定常系统又称为时不变系统,其特点是:系统的自身性质(所研究物体的本质属性例如:质量.转动惯量等)不随时间而变化.具体 ...

  3. Chrome 53 Beta一些有意思的改动

    原文链接: http://blog.chromium.org/2016...译者:Icarus邮箱:xdlrt0111@163.com 如果没有特殊说明的话,以下都是应用在Android,Chrome ...

  4. 文档声明(Doctype)和<!Doctype html>有何作用? 严格模式与混杂模式如何区分?它们有何意义?

    文档声明的作用: 文档声明是为了告诉浏览器,当前HTML文档使用什么版本的HTML来写的,这样浏览器才能按照声明的版本来正确的解析. <!doctype html> 的作用就是让浏览器进入 ...

  5. Mybatis分页查询total中的坑

    写在前面 今天用mybatis进行分页查询,大家应该都用过pageHelper这个插件,但是在计算总的数据数的时候,page.getTotal()总是返回0,要么就是返回pageSize(),今天给大 ...

  6. C#多线程下的调优

    一.原子操作 先看一段问题代码 /// <summary> /// 获取自增 /// </summary> public static void GetIncrement() ...

  7. MySQL5.6复制技术

    mysql复制功能介绍 我们可以通过为服务器配置主从即一个或多个备库的方式,以及主主结构来进行数据同步,将MySQL的数据分布到多个系统上去.复制过程中一台主库(master)服务器可以数据被同步到多 ...

  8. docker基础容器中bash: vi: command not found问题解决

    安装即可 1.apt-get update 2.apt-get install vim

  9. Unity通过脚本创建Mesh(网格)

    ##1.创建一个带Mesh的物体 Unity中的网格作为组件不能脱离物体单独存在 新建脚本CreateMesh public class CreateMesh: MonoBehaviour { voi ...

  10. 学生管理系统(python实现)

    # 定一个列表,用来存储所有的学生信息(每个学生是一个字典) info_list = [] def print_menu(): print("------------------" ...