广告
返回顶部
首页 > 资讯 > 数据库 >Redis 的持久化
  • 472
分享到

Redis 的持久化

Redis的持久化 2018-01-28 08:01:26 472人浏览 才女
摘要

原文链接: https://www.changxuan.top/?p=1386   Redis 是一个非关系型的内存数据库,使用内存存储数据是它能够进行快速存取数据的原因之一。 在实际应用中,常有人提倡把 Redis 只作为一种能够提高

Redis 的持久化

原文链接: https://www.changxuan.top/?p=1386


 

Redis 是一个非关系型的内存数据库,使用内存存储数据是它能够进行快速存取数据的原因之一。

在实际应用中,常有人提倡把 Redis 只作为一种能够提高用户体验的组件来使用, 也就是说即使 Redis 服务挂掉之后也要保证系统正常使用。不过,在很多系统中还是希望既能发挥 Redis 基于内存快速存取的特性,又希望机器断电或 Redis服务停止后数据不丢失。所以,才引出了 Redis 的持久化功能。

在许多技术文章中,提到 Redis 的持久化时往往都会直接抛出两个名词 RDB 和 AOF。然后接下来就是分别介绍这两个名词。当然,如果要谈 Redis 的持久化肯定避免不了讲 RDB 和 AOF,但这是介绍持久化最恰当的方式吗?这样的文章是不是显得有些生硬呢?所以,在尝试弄明白一个事物的原理时一定要从头到尾的思考它存在的意义?为了解决什么问题?采用了什么方式?达到了什么目的?自己有没有其它的方案?这样从问题的源头切入,才能对这个事物理解的更加深刻,从而能够更好的帮助自己进行举一反三。而不是人云亦云,对于一些知识仅仅是背诵下来,这种死记硬背下来的知识在脑海里的保质期也是短的可怜。

在前面,我们已经提到为什么需要引入持久化?简单的来说持久化就是把内存中的数据存储到外存上,这样服务停止后,当再启动的时候就可以把外存的数据读取到内存中从而达到了不丢失数据的目的。

RDB

如果让你设计一个持久化的方案,你会怎么做呢?(假装绞尽脑汁… …)首先,我们可以使用一种简单的策略,将 Redis 中所有的数据按照一定格式全部写到磁盘上,即创建数据的快照文件。然后,你为了尽量保证不丢数据需要考虑使用实时写还是定时写,又或者用其它策略。其实,现在的你已经在尝试着去实现 RDB (Redis Database)持久化的机制了。所以,你看它其实并不难。万丈高楼从地起,先从一个简单的 idea 开始,逐渐去完善它,丰富它的过程便是解决问题的过程。例如用这种思路去学习计算机网络也是同样适用的,你可以给自己出一个问题“如何让两台电脑进行通信?”,自己想办法解决这个问题的过程肯定会比在计算机网络课堂上收获的知识更多,也更牢固。

尽管不需要我们写代码来实现 RDB 持久化,但是并不妨碍我们来思考一下假如让我们来实现的话大概会遇到哪些问题?例如:什么时候生成数据快照?文件数据格式的定义?如果在主进程中进行持久化,阻塞客户端的请求后会不会有影响?接下来,我们就看一下 RDB 是如何做的吧。

基本命令

在 Redis 中,提供了两个 RDB 持久化的命令: SAVE 和 BGSAVE 。执行 SAVE 时,Redis 服务会停止处理任何客户端的命令请求;执行 BGSAVE 时,Redis 服务则会创建一个子进程,由子进程来负责数据的持久化,而此时 Redis 服务就可以正常处理客户端的请求。

BGSAVE 解决了我们对于持久化时是否会影响 Redis 服务处理客户端的请求的担心。

自动间隔性保存

自动间隔性保存,则解决了“什么时候生成数据快照?”的问题。在 Redis 的配置文件中我们可以写入以下配置:

save 600 1
save 300 10
save 60 100
save 30 1000

上面的配置表示,如果在 600 秒内对数据库进行了 1 次修改,就执行执行一次 BGSAVE 命令;如果在 300 秒内对数据库进行了 10 次修改,就执行一次 BGSAVE 命令;以此类推。你可以根据你的业务场景,配置 save 的参数,也不仅仅局限于 4 条配置。

实现原理

在 Redis 启动时,会把上述配置存储到 Redis 服务器的状态中,具体的结构体则是 redisServer,存储 save 参数的结构体为 saveparam。

 1 // Redis 服务器状态信息结构体
 2 struct redisServer {
 3     // ... ...
 4  
 5     // 记录多个 save 配置参数
 6     struct saveparam *saveparams;
 7     // 修改次数计数器
 8     long long dirty;
 9     // 上次执行保存的时间
10     time_t lastsave;
11  
12     // ... ...
13 }
14 // Save 参数结构体 saveparam
15 struct saveparam {
16     // 秒数
17     time_t seconds;
18     // 修改数
19     int changes;
20 }

 

看到上面 redisServer 结构体的属性信息,你心里应该有答案了吧?dirty 表示的是自从上次执行 SAVE 或者 BGSAVE 命令完成之后对数据库进行修改的次数;lastsave 表示的是上次成功执行SAVE 或者 BGSAVE 命令的时间。这个时候,如果再有个机制能够定时检查是否有满足条件的配置参数就可以了。

Redis 提供了一个周期性操作函数 serverCron,每 100 ms 会执行一次。它其中的一项工作就是来检查是否有符合条件的 save 参数,如果存在符合条件的参数则执行 BGSAVE 命令,执行完毕之后将 dirty 和 lastsave 的值重置。相信只要有基础的编程知识,根据这些变量就能实现这个检查的过程吧。

文件结构

RDB 文件结构示意图

在上图中,大写字母的单词表示的常量,小写字母单词则是变量和数据。RDB 文件开头的“REDIS”是我们习惯称为的魔数,类似于 class 文件的 COFFEE,用来识别文件类型;紧接着长度为四个字节的 db_version 记录的是 RDB 文件的版本号;database 表示的是所存储的数据;EOF 则表明数据内容结束了;check_sum 的值是整个文件的校验和,用来检查文件是否损坏。

AOF

其实持久化数据除了 RDB 这种方式,肯定会有同学能想到另一种方式,就是把服务端执行的所有客户端请求增加、修改和删除等会改变数据的命令全都存储起来。通过存储这些命令数据,在遇到机器宕机和服务进程异常中断的情况下重启服务时只要执行一遍这些持久化的命令即可恢复之前的数据了。(也是一个相当好的办法呀!)

原理就是如此,那么问题来了,假如同样让你来实现这个过程,你会考虑到哪些问题呢?

一是性能问题,执行完命令之后是否直接将此命令持久化到磁盘上还是由操作系统控制文件同步?在这个问题上如何做取舍?二是文件大小问题,随着 Redis 服务运行越来越久,数据文件势必会越来越大?应该使用什么办法解决?… …

我们来看下 Redis 的 AOF 的过程吧!

持久化过程

首先,通过在配置文件中增加一行配置 appendonly yes 来开启 AOF 持久化。

像 RDB 机制所依赖 redisServer 结构体中的 saveparams、dirty、lastsave 参数一样,AOF 的实现依赖 redisServer 结构体中的 aof_buf 参数。

1 struct redisServer{
2     // ... ...
3  
4     // AOF 缓冲区
5     sds aof_buf;
6  
7     // ... ...
8 }

 

aof_buf 参数用来以协议格式缓存会对数据进行变更的命令。

在 Redis 服务器执行完命令,并将命令以协议的格式追加到 aof_buf 缓冲区之后,在当前这个事件循环结束之前,Redis 还会调用一个函数 flushAppendOnlyFile,这个函数会根据配置文件中 appendfsync 的值来决定接下来的持久化行为。appendfsync 有三个可选值,分别是 always、everysec、no

  • always: 将 aof_buf 缓冲区中的内容写入并同步到 AOF 文件。(性能最低,安全最高)
  • everysec: 将 aof_buf 缓冲区中的内容写入到 AOF 文件,如果上次同步 AOF 文件的时间距离现在超过一秒钟,那么再次对 AOF 文件同步,并且这个同步是由一个线程专门负责的。(同时兼顾性能与安全,推荐)
  • no: 将 aof_buf 缓冲区中的内容写入到 AOF 文件,但并不负责对 AOF 文件的同步,把同步的控制权交由操作系统控制。(性能最高,安全最低)

以上就是 AOF 持久化的基本过程。

数据载入

由于命令数据是以协议格式存储至文件中的,所以在启动 Redis 服务时检测到 AOF 文件的存在后会启动载入程序。(如果 RDB 和 AOF 持久化的文件同时存在则会优先载入 AOF 文件数据)

启动载入程序后,其载入过程如下图所示:

AOF 重写

在前面,我们提到 AOF 的这种机制会造成 AOF 数据文件越来越大,并且可能会存在许多无意义的命令。例如,先执行了一个命令 set chang xuan ,随后又执行了命令 del chang 。其实这两条语句都会被持久化到 AOF 文件中,但实际上除了能证明曾经执行过这两条命令之外对于我们要持久化数据的目的而言并没有什么作用。

对此,Redis 提供了 AOF 重写的机制。

Redis 的 AOF 重写其实是根据当前存储的数据,生成命令的过程。并且会采用一些策略尽量减小 AOF 文件的大小,例如对于 List 中的数据会尽量使用较少的命令操作较多的数据。当然,如果在当前进程中进行重写处理并且数据量特别大的情况下肯定会阻塞客户端的请求,所以和 RDB 一样,Redis 提供了 AOF 后台重写的机制。

后台重写(BGREWRITEAOF)

AOF 通过 fork 子进程的方式进行后台重写有两个优点:

  1. 重写期间服务器进程可以继续处理请求。
  2. 子进程带有服务器进程的数据副本,能充分利用操作系统提供的写时复制机制从而提升效率,还可以在避免使用的情况下保证数据的安全性。

天下没有免费的午餐,这种方式还带来一个问题。就是在使用子进程重写期间,如果父进程还在处理着客户端请求,如何保证重写后 AOF 文件数据的一致性呢?

对于这个问题,Redis 设置了一个 AOF 重写缓冲区。在子进程被创建后,Redis 服务器就会启用这个重写缓冲区。在将命令以协议格式追加到 AOF 缓冲区之后,同时也会追加到 AOF 重写缓冲区。

当子进程完成重写工作后会向父进程发送一个信号。父进程接收到信后之后会进行调用相关函数,进行以下工作:

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

这时,就完成了一次 AOF 后台重写。

总结

通过前文内容,我们可以大致清楚 Redis 所提供的 RDB 和 AOF 两种持久化机制的过程以及基本原理。它们各有特点,也各有适合使用的场景所以并不能说谁一定比谁好。通过搭配使用,能够确保线上环境数据的安全性就是最好的。

您可能感兴趣的文档:

--结束END--

本文标题: Redis 的持久化

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

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

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

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

下载Word文档
猜你喜欢
  • redis的持久化
    为什么要持久化?在不考虑服务器宕机的情况下,是不需要把内存中的数据保存到磁盘,来做持久化的。持久化,就是专门为宕机准备的补救措施。redis有rdb和aof两种持久化机制。一、RDB (Redis Data...
    99+
    2022-10-18
  • Redis 的持久化
    原文链接: https://www.changxuan.top/p=1386   Redis 是一个非关系型的内存数据库,使用内存存储数据是它能够进行快速存取数据的原因之一。 在实际应用中,常有人提倡把 Redis 只作为一种能够提高用...
    99+
    2018-01-28
    Redis 的持久化
  • Redis的持久化RDB
    dbfilename redis.db  //持久化的文件dir /home/redis/6379    //文件所在目录save 900 1  ...
    99+
    2022-10-18
  • Redis之持久化
    redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到硬盘来保证持久化。redis支持两种持久化方式: 1、snapshotting(快照)也是默认方式。将内存中的数据以快照...
    99+
    2022-10-18
  • redis的两种持久化
    1、前言Redis是一种高级key-value数据库。它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富。有字符串,链表,集 合和有序集合。支持在服务器端计算集合的并,交和补集(dif...
    99+
    2022-10-18
  • Redis的持久化介绍
    一、持久化的作用1.什么是持久化redis的所有数据保存在内存中,对数据的更新将异步的保存到硬盘上2.持久化的实现方式快照:某时某刻数据的一个完成备份    -mysql的Dump &n...
    99+
    2022-10-18
  • redis 的持久化机制
    redis 持久化机制有两种:RDB 和 AOF。 RDB RDB 机制是对 redis 中的数据执行周期性的持久化。每个几分钟、几小时、几天生成 redis 内存中的数据的一份完整的快照。 AOF 每条写入命令作为日志,写入 aof 文...
    99+
    2015-09-25
    redis 的持久化机制
  • redis持久化的介绍
    1. RDB 1.1 RDB简介 RDB:在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里。 工作机制:每隔一段时间,就把内存中的数据保...
    99+
    2022-10-18
  • 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 持久化
  • Redis如何监控持久化和优化持久化?
    Redis持久化过程一直是影响redis性能的常见因素,如何监控持久化以及如何优化持久化过程呢?下面我们就一起来看看吧。fork的监控及优化不管是使用哪种持久化,RDB持久化或AOF重写,主进程都会fork...
    99+
    2022-10-18
  • Redis持久化机制
    1、Redis数据持久化的必要性 由于redis是基于内存的数据库,面临数据掉电易失的风险,要避免数据丢失,最好将内存数据持久化到磁盘等永久存储介质上。服务重启时,会先加载磁盘文件内的数据到内存,完成数据恢复。 2、RDB(Red...
    99+
    2020-06-06
    Redis持久化机制
  • redis数据持久化
    1 redis是内存型的数据库 redis数据放在内存中 重启服务器丢失数据 重启redis服务丢失数据 断电丢失数据 为了防止redis数据丢失, 进行持久化, 所以将数据写入到一个文件中来实现 2 rdb持久化 在配置文件中, 添加rd...
    99+
    2021-06-10
    redis数据持久化
  • redis持久化存储
    redis持久化存储 redis持久化存储 redis多被用于缓存和消息中间件,当被用作缓存时,数据的读写都是在内存中进行的,而内存一旦在主机断电或者主机重启时里面的数据将被清空,为保证数据不被丢失,r...
    99+
    2020-12-12
    redis持久化存储
  • Redis之--rdb持久化
    持久化:通俗讲,下次开机还有数据,断电后不会丢失数据,存放于磁盘。 Redis:rdb快照持久化每隔N分钟或N次写操作后,从内存dump数据形成RDB文件。压缩,放在备份目录。 参数详解:从下往上看save...
    99+
    2022-10-18
  • Redis 持久化详解
    http://www.redis.cn/topics/persistence.html 持久化 Redis 如同其他的存储组件一样,提供了两类持久化方式:快照,和全量追加日志。 RDB - 快照 在默认情况下, Redis 将数据库...
    99+
    2015-08-16
    Redis 持久化详解
  • Redis持久化之AOF
    背景:RDB不足之处1.耗时,耗性能生成快照文件耗时,load快照文件耗时Fork子进程网络开销写文件磁盘I/O开销 2.不可控,丢失数据会丢失最后一次快照最后操作的数据。 一、工作流程Redis写操作...
    99+
    2022-10-18
  • redis怎么持久化
    redis怎么持久化?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。redis怎么持久化1.RDB保存多份完整备份,对 IO 影...
    99+
    2022-10-18
  • Redis(四):持久化之---AOF持久化的配置和原理
    AOF持久化及AOF重写的配置:默认AOF方式是关闭的,如下图:如果要开启的话,就是把no改写成yes。如下图:默认文件名称appendonly.aof,你也可以修改文件名。默认保存目录同样也是配置文件中d...
    99+
    2022-10-18
  • redis 详解(4)持久化
    定义 redis 所有数据保存在内存中,对数据更新将异步保存到磁盘 持久化的作用 方式 说明 快照 mysql dump,redis RDB 日志 mysql binlog,redis AOF,hbase Hlog ...
    99+
    2020-07-06
    redis 详解(4)持久化
  • Redis学习之持久化
    简介 持久化是将内存中的瞬时数据,转换为存储在磁盘上的持久数据。redis是一个将数据存储在内存中的数据库,这也是它高效率的原因之一。但是将数据存储在内存,如果遇到突发事件,可能会造成数据的丢失。所以我们需要将数据持久化,等下次redis启...
    99+
    2019-03-12
    Redis学习之持久化
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作