iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >深入理解redis的持久化
  • 584
分享到

深入理解redis的持久化

2024-04-02 19:04:59 584人浏览 薄情痞子
摘要

最近工作之余学习了一下Redis,这里简单的理解一下redis持久化; Redis提供的持久化机制 Redis是一种面向“key-value”类型数据的分布式NoSQL数据库系统,具有高


最近工作之余学习了一下Redis,这里简单的理解一下redis持久化;


Redis提供的持久化机制

Redis是一种面向“key-value”类型数据的分布式NoSQL数据库系统,具有高性能、持久存储、适应高并发应用场景等优势。它虽然起步较晚,但发展却十分迅速。 


一、Redis持久化是如何工作的?

    什么是持久化?简单来讲就是将数据放到断电后数据不会丢失的设备中,也就是我们通常理解的硬盘上。

 

首先我们来看一下数据库在进行写操作时到底做了哪些事,主要有下面五个过程:

(1)客户端向服务端发送写操作(数据在客户端的内存中)。

(2)数据库服务端接收到写请求的数据(数据在服务端的内存中)。

(3)服务端调用write这个系统调用,将数据往磁盘上写(数据在系统内存的缓冲区中)。

(4)操作系统将缓冲区中的数据转移到磁盘控制器上(数据在磁盘缓存中)。

(5)磁盘控制器将数据写到磁盘的物理介质中(数据真正落到磁盘上)。

 

1、故障分析:

写操作大致有上面5个流程,下面我们结合上面的5个流程看一下各种级别的故障: 

 

(1)当数据库系统故障时,这时候系统内核还是完好的。那么此时只要我们执行完了第3步,那么数据就是安全的,因为后续操作系统会来完成后面几步,保证数据最终会落到磁盘上。

(2)当系统断电时,这时候上面5项中提到的所有缓存都会失效,并且数据库和操作系统都会停止工作。所以只有当数据在完成第5步后,才能保证在断电后数据不丢失。

 

通过上面5步的了解,可能我们会希望搞清下面一些问题: 

(1)数据库多长时间调用一次write,将数据写到内核缓冲区?

(2)内核多长时间会将系统缓冲区中的数据写到磁盘控制器?

(3)磁盘控制器又在什么时候把缓存中的数据写到物理介质上?

 

对于第一个问题,通常数据库层面会进行全面控制。

而对第二个问题,操作系统有其默认的策略,但是我们也可以通过POSIX api提供的fsync系列命令强制操作系统将数据从内核区写到磁盘控制器上。

对于第三个问题,好像数据库已经无法触及,但实际上,大多数情况下磁盘缓存是被设置关闭的,或者是只开启为读缓存,也就是说写操作不会进行缓存,直接写到磁盘。

建议的做法是仅仅当你的磁盘设备有备用电池时才开启写缓存。


2、数据损坏 

    所谓数据损坏,就是数据无法恢复,上面我们讲的都是如何保证数据是确实写到磁盘上去,但是写到磁盘上可能并不意味着数据不会损坏。比如我们可能一次写请求会进行两次不同的写操作,当意外发生时,可能会导致一次写操作安全完成,但是另一次还没有进行。如果数据库的数据文件结构组织不合理,可能就会导致数据完全不能恢复的状况出现。 

这里通常也有三种策略来组织数据,以防止数据文件损坏到无法恢复的情况:

(1)第一种是最粗糙的处理,就是不通过数据的组织形式保证数据的可恢复性。而是通过配置数据同步备份的方式,在数据文件损坏后通过数据备份来进行恢复。实际上mongoDB在不开启操作日志,通过配置Replica Sets时就是这种情况。

(2)另一种是在上面基础上添加一个操作日志,每次操作时记一下操作的行为,这样我们可以通过操作日志来进行数据恢复。因为操作日志是顺序追加的方式写的,所以不会出现操作日志也无法恢复的情况。这也类似于MonGoDB开启了操作日志的情况。

(3)更保险的做法是数据库不进行旧数据的修改,只是以追加方式去完成写操作,这样数据本身就是一份日志,这样就永远不会出现数据无法恢复的情况了。实际上CouchDB就是此做法的优秀范例。

 

 

二 、Redis提供了RDB持久化和AOF持久化

 

1、RDB机制的优势和劣势

RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。

也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。

 

A、优势

(1)一旦采用该方式,那么你的整个Redis数据库将只包含一个文件,这样非常方便进行备份。比如你可能打算没1天归档一些数据。

(2)方便备份,我们可以很容易的将一个一个RDB文件移动到其他的存储介质上

(3)RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

(4)RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。

 

B、劣势

(1)如果你需要尽量避免在服务器故障时丢失数据,那么 RDB 不适合你。 虽然 Redis 允许你设置不同的保存点(save point)来控制保存 RDB 文件的频率, 但是, 因为RDB 文件需要保存整个数据集的状态, 所以它并不是一个轻松的操作。 因此你可能会至少 5 分钟才保存一次 RDB 文件。 在这种情况下, 一旦发生故障停机, 你就可能会丢失好几分钟的数据。

(2)每次保存 RDB 的时候,Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。 在数据集比较庞大时, fork() 可能会非常耗时,造成服务器在某某毫秒内停止处理客户端; 如果数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。 虽然 AOF 重写也需要进行 fork() ,但无论 AOF 重写的执行间隔有多长,数据的耐久性都不会有任何损失。

 

可以通过配置设置自动做快照持久化的方式。我们可以配置redis在n秒内如果超过m个key被修改就自动做快照,下面是默认的快照保存配置

   save 900 1     #900秒内如果超过1个key被修改,则发起快照保存

   save 300 10    #300秒内容如超过10个key被修改,则发起快照保存

   save 60 10000

 

2、RDB文件保存过程

(1)redis调用fork,现在有了子进程和父进程。

(2)父进程继续处理client请求,子进程负责将内存内容写入到临时文件。由于os的写时复制机制(copy on write)父子进程会共享相同的物理页面,当父进程处理写请求时os会为父进程要修改的页面创建副本,而不是写共享的页面。所以子进程的地址空间内的数 据是fork时刻整个数据库的一个快照。

(3)当子进程将快照写入临时文件完毕后,用临时文件替换原来的快照文件,然后子进程退出。

 

client 也可以使用save或者bgsave命令通知redis做一次快照持久化。save操作是在主线程中保存快照的,由于redis是用一个主线程来处理所有 client的请求,这种方式会阻塞所有client请求。所以不推荐使用。

另一点需要注意的是,每次快照持久化都是将内存数据完整写入到磁盘一次,并不 是增量的只同步脏数据。如果数据量大的话,而且写操作比较多,必然会引起大量的磁盘io操作,可能会严重影响性能。

 

3、AOF文件保存过程

redis会将每一个收到的写命令都通过write函数追加到文件中(默认是 appendonly.aof)。

当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。当然由于os会在内核中缓存 write做的修改,所以可能不是立即写到磁盘上。这样aof方式的持久化也还是有可能会丢失部分修改。不过我们可以通过配置文件告诉redis我们想要 通过fsync函数强制os写入到磁盘的时机。有三种方式如下(默认是:每秒fsync一次

 

appendonly yes            //启用aof持久化方式

# appendfsync always      //每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用

appendfsync everysec      //每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐

# appendfsync no    //完全依赖os,性能最好,持久化没保证

 

AOF 的方式也同时带来了另一个问题。持久化文件会变的越来越大。例如我们调用incr test命令100次,文件中必须保存全部的100条命令,其实有99条都是多余的。因为要恢复数据库的状态其实文件中保存一条set test 100就够了。

为了压缩aof的持久化文件。redis提供了bgrewriteaof命令。收到此命令redis将使用与快照类似的方式将内存中的数据 以命令的方式保存到临时文件中,最后替换原来的文件。具体过程如下

(1)redis调用fork ,现在有父子两个进程

(2)子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令

父进程继续处理client请求,除了把写命令写入到原来的aof文件中。同时把收到的写命令缓存起来。这样就能保证如果子进程重写失败的话并不会出问题。

当子进程把快照内容写入已命令方式写到临时文件中后,子进程发信号通知父进程。然后父进程把缓存的写命令也写入到临时文件。

(3)现在父进程可以使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加。

(4)需要注意到是重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。

 

A、优势

(1)使用 AOF 持久化会让 Redis 变得非常耐久(much more durable):你可以设置不同的 fsync 策略,比如无 fsync ,每秒钟一次 fsync ,或者每次执行写入命令时 fsync 。 AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,所以主线程可以继续努力地处理命令请求)。

(2)AOF 文件是一个只进行追加操作的日志文件(append only log), 因此对 AOF 文件的写入不需要进行 seek , 即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等等), redis-check-aof 工具也可以轻易地修复这种问题。
    (3)Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。

 

(4)AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。

 

B、劣势

(1)对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。

(2)根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。

(3)AOF 在过去曾经发生过这样的 bug : 因为个别命令的原因,导致 AOF 文件在重新载入时,无法将数据集恢复成保存时的原样。 (举个例子,阻塞命令 BRPOPLPUSH 就曾经引起过这样的 bug 。) 测试套件里为这种情况添加了测试: 它们会自动生成随机的、复杂的数据集, 并通过重新载入这些数据来确保一切正常。 虽然这种 bug 在 AOF 文件中并不常见, 但是对比来说, RDB 几乎是不可能出现这种 bug 的。

 

3、抉择

一般来说, 如果想达到足以媲美 postgresql 的数据安全性, 你应该同时使用两种持久化功能。

如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。

其余情况我个人喜好选择AOF

 

4、如果 AOF 文件出错了,怎么办?

服务器可能在程序正在对 AOF 文件进行写入时停机, 如果停机造成了 AOF 文件出错(corrupt), 那么 Redis 在重启时会拒绝载入这个 AOF 文件, 从而确保数据的一致性不会被破坏。

 

当发生这种情况时, 可以用以下方法来修复出错的 AOF 文件:

(1)为现有的 AOF 文件创建一个备份。

(2)使用 Redis 附带的 redis-check-aof 程序,对原来的 AOF 文件进行修复。

$ redis-check-aof --fix

(3)[可选]使用 diff -u 对比修复后的 AOF 文件和原始 AOF 文件的备份,查看两个文件之间的不同之处。

重启 Redis 服务器,等待服务器载入修复后的 AOF 文件,并进行数据恢复。

 

 

作者:SEian.G(苦练七十二变,笑对八十一难)



您可能感兴趣的文档:

--结束END--

本文标题: 深入理解redis的持久化

本文链接: https://www.lsjlt.com/news/47983.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 深入理解redis的持久化
    最近工作之余学习了一下redis,这里简单的理解一下redis持久化; Redis提供的持久化机制 Redis是一种面向“key-value”类型数据的分布式NoSQL数据库系统,具有高...
    99+
    2024-04-02
  • redis的2种持久化方案深入讲解
    前言 Redis是一种高级key-value数据库。它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富。有字符串,链表,集 合和有序集合。支持在服务器端计算集合的并,交和补集(dif...
    99+
    2024-04-02
  • 关于Redis持久化的深入探究
    目录Redis持久化1、为什么需要持久化2、RDB(Redis Database)2.1 官网介绍2.2 什么是RDB2.3 操作步骤3、AOF(Append Only File)3.1 什么是AOF?3.2 AOF持久...
    99+
    2023-05-22
    Redis持久化详解 Redis 持久化
  • Redis的持久化详解
    目录一、Redis的持久化二、RDB(Redis DataBase)1、RDB快照原理2、RDB配置3、redis.conf 其他一些配置4、RDB的备份恢复5、RDB优缺点三、AOF(Append Of File)1、...
    99+
    2023-06-05
    Redis持久化详解 Redis 持久化
  • Vuex模块化与持久化深入讲解
    目录概述Vuex的模块化state数据状态对象getters计算属性对象actions异步请求对象mutations数据同步对象Vuex的使用方式在自定义组件中使用在自定义js文件中...
    99+
    2023-01-06
    Vuex模块化与持久化 Vuex模块化 Vuex持久化
  • Redis中AOF与RDB持久化策略深入分析
    目录写在前面一、Redis为什么要持久化二、Redis的持久化方式2.1. AOF持久化(Append of file)2.1.1 fsync 系统调用2.1.2 AOF持久化策略2.1.3 aof_rewrite2.2...
    99+
    2022-11-28
    Redis持久化策略 RedisAOF RedisRDB
  • Redis之持久化
    redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到硬盘来保证持久化。redis支持两种持久化方式: 1、snapshotting(快照)也是默认方式。将内存中的数据以快照...
    99+
    2024-04-02
  • redis持久化的介绍
    1. RDB 1.1 RDB简介 RDB:在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里。 工作机制:每隔一段时间,就把内存中的数据保...
    99+
    2024-04-02
  • redis怎么持久化
    redis怎么持久化?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。redis怎么持久化1.RDB保存多份完整备份,对 IO 影...
    99+
    2024-04-02
  • Node.js LoopBack 的数据持久化:深入了解存储机制
    Node.js LoopBack 是一款强大的开发框架,用于构建 REST API 和微服务。它提供了一系列功能,包括数据持久化,使开发人员能够轻松地存储和管理数据。 存储机制 LoopBack 支持多种存储机制,包括: 关系数据库管理...
    99+
    2024-04-02
  • Redis中持久化原理是什么
    这篇文章将为大家详细讲解有关Redis中持久化原理是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Redis持久化机制:## 写在前面本文从整体上详细介绍Redis的...
    99+
    2024-04-02
  • Redis持久化原理实例分析
    今天小编给大家分享一下Redis持久化原理实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一...
    99+
    2024-04-02
  • Redis持久化的底层原理是什么
    Redis持久化的底层原理是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。RDB(默认)RDB是通过快照方式完成的,当满足一定条件时,...
    99+
    2024-04-02
  • 【Redis】Redis持久化之AOF详解(Redis专栏启动)
    📫作者简介:小明java问道之路,2022年度博客之星全国TOP3,专注于后端、中间件、计算机底层、架构设计演进与稳定性建工设优化。文章内容兼具广度深度、大厂技术方案,对待技术喜欢推理加验证,就职于知名金融公司后端高级...
    99+
    2023-09-05
    redis 缓存 数据库 java AOF
  • Redis持久化的配置方法
    这篇文章主要介绍“Redis持久化的配置方法”,在日常操作中,相信很多人在Redis持久化的配置方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Redis持久化的配置方法”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-06
  • redis持久化的示例分析
    这篇文章给大家分享的是有关redis持久化的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。为什么需要持久化?由于Redis是一种内存型数据库,即服务器在运行时,系统为其分...
    99+
    2024-04-02
  • Redis高可用之持久化
    目录一、高可用什么是高可用二、Redis持久化持久化功能RDB持久化 触发条件bgsave执行流程AOF持久化执行流程命令追加文件写入和文件同步文件重写文件重写流程三、RDB和AOF的优缺点RDB持久化的优缺点...
    99+
    2023-04-07
    Redis高可用之持久化 Redis高可用 Redis持久化
  • redis如何开启持久化
    redis开启持久化的方法:在redis.conf配置文件中设置开启。开启AOF持久化的配置方法:# 是否开启aofappendonly yes# 文件名称appendfilename "appendonly.aof"# 同步方式appen...
    99+
    2024-04-02
  • redis怎么开启持久化
    redis开启持久化的方法:在redis.conf配置文件中设置开启。AOF的的持久化配置方法:# 是否开启aofappendonly yes# 文件名称appendfilename "appendonly.aof"# ...
    99+
    2024-04-02
  • redis持久化db失效如何解决
    当Redis持久化的数据库(db)失效时,可以通过以下几个步骤来解决问题:1. 检查是否启用了持久化机制:使用命令`config g...
    99+
    2023-08-31
    redis
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作