Redis持久化策略(看这篇,你肯定会有所获)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis持久化策略(看这篇,你肯定会有所获)相关的知识,希望对你有一定的参考价值。

参考技术A RDB:Redis DataBase , 记录快照

        RDB是redis 默认的持久化方案. RDB 是当满足一定条件时, 就会将redis内存中的数据写入磁盘,并生成一个快照文件dump.rdb 文件.Redis 重启会通过加载dump.rdb文件恢复数据.

        一定条件分为以下几种情况: 1.自动触发  2. 手动触发 . 下面分开说明下:

a).redis.conf 中 SNAPSHOTTING 其中定义了触发把数据保存到磁盘的触发频率.

        如果不需要rdb 方案, 注释save 或者配置成空字符串" ".

        save 900 1 #900秒内至少有一个key被修改(包括添加)

        save 300 10 #400秒内至少10个key被修改

        save 10000 #60秒内至少有10000个key 被修改.

        这三条配置不冲突, 只要满足一条就触发.

        rdb 文件位置和目录 (默认在安装根目录下) 

        #文件路径

        dir ./

        #文件名称

        dbfilename dump.rdb

        #是否以LZY压缩rdb 文件

        rdbcompression yes 

        #开启数据校验

        rdbchecksum yes

b) shutdown触发 ,保证服务器正常关闭.

c) flushall , rdb文件是空的, 会生成一个空的文件,所以这种情况也没有什么意义.但需要知道,这种情况下

会触发生成rdb文件.

Redis 提供了两条命令: save 和 bgsave

a). save 命令

        save 在生成快照的时候会阻塞当前Redis 服务器,Redis不能处理其他命令.如果内存数据较多,会造成

b).bgsave 命令

        执行bgsave命令时,   Redis会在后台进行异步快照操作,快照同时还可以响应客户端请求.

具体操作

        具体操作:Redis进程会执行fork操作创建子进程(copy-on-write),RDB 持久化过程由子进程负载,完成后自动结束.它不会记录fork之后产生的记录.阻塞只发送在fork阶段,一般时间较短.

一.优势

    1.RDB是一个非常紧凑的文件,它保存了Redis在某个时间点上的数据集.这种文件非常适合进行备份和

灾难恢复.

    2.生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存的工作,主进程不需要进行任何

IO操作.

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

二.劣势

    1).RDB 没办法做到实时持久化/妙级持久化.因为bgsave每次运行都要执行fork创建子进程,频繁执行成本过高.    

    2).在一定间隔时间做一次备份,所以如果Redis 以为down掉的话,就会丢失最后一次快照之后所有修改

(数据有丢失)

AOF:<Append Only File> , 记录日志

Redis 默认不开启.AOF采用日志的形式来记录每个写操作,并追加到文件中.开启后,执行更改Redis    命令时,就会把命令写入到AOF文件中.

Redis 重启时会根据日志文件的内容把写指令从前往后执行一次以完成数据的恢复工作.

#开关

appendonly no

#文件名

appendfilename "appendonly.aof"

        由于操作系统缓存机制,AOF数据并没有真正地写入硬盘,而是进入了系统的硬盘缓存.什么时候

把缓冲区的内容写入到AOF文件中? 由下面参数决定

appendfsync :  值: no  \ always \everysec 

        no: 表示不执行fync, 由操作系统保证数据同步到磁盘,速度最快,但是不安全.

        always:表示每次写入都执行fync,以保证数据同步到磁盘,效率很低

        everysec:表示每秒执行以fync ,可能会导致丢失1s数据.通常选择everysec,兼顾效率和安全性.

    因为AOF文件只有一个, 随着redis 不断进行,AOF 的文件会越来越大,文件越大, 文件占用服务器内存

以及AOF恢复要求时间越长.

    为了解决这个问题,可以使用bgwriteaof来重写.那什么时候重写? 又是怎样重写?

    一. 什么时候重写?

    #重写触发机制

    auto-aof-rewrite-percentage 100 默认值是100. 当前aof 文件大小超过 上一次重写的aof文件大小百分之多少进行重写,即当aof文件增长到一定大小时,Redis能够调用bgwriteaof对日志文件进行重写.当前aof文件大小是上次日志重写得到aof文件大小的二倍时, 自动启动新的日志重写过程.

    auto-aof-rewrite-min-size 默认是64M.设置允许重写的最小aof文件大小,避免达到了约定百分比 但尺寸

仍然很小的情况还要重写.

   二. 怎样重写?

    并不是对原文件进行重新整理,而是直接读取服务器上现有的键值对,然后用一条命令去代替之间记录这

个键值对的多条命令,生成一个新的文件后去替换原来的 AOF文件.

    看下面这两个参数:

        no-appendfsync-on-rewrite

        aof-load-truncated

   AOF 数据恢复

        重启Redis之后就会进行AOF文件恢复.

   AOF 的优势和劣势

优点:

1.AOF 持久化的方法提供了多种的同步频率,即使使用默认的同步频率每秒同步一次,Redis最多也就丢失

1秒的数据.

缺点:

1.对于具有相同数据的Redis, AOF文件通常比RDF文件体积更大(RDB存的是数据快照)

2.虽然AOF提供了多种同步的频率,默认的情况下,没秒同步一次的频率也具有较高的性能.在高并发的情况下,RDB比AOF具有更好的性能.

        如果可以忍一小段时间数据的丢失,毫无疑问使用RDB 是最好的,定时生成RDB快照非常便于进行数据备份,而且RDB恢复数据集的速度也要比AOF恢复速度要快.

        否则就要使用AOF重写.但是一般情况下建议不要单独使用某一种持久化机制,而是两种一起用.

本文内容来自咕泡学院-青山老师,感谢青山老师!!

如何让 Redis 更持久?本文教你!

点击关注公众号,Java干货及时送达

最近在面试的路上愈走愈远了,Redis肯定是一个热门面试方向。像有几种数据结构?如何实现延迟队列?淘汰机制是怎么样的?都快问到麻木,这些问题还常绕脑梁。那我们这篇就举一个比较常见且难度适中的面试题来聊聊。Redis 的持久化策略是怎么样的?

开局问个问题,相信被问到 Redis 持久化 的同学肯定不在少数,答对的同学肯定也不在少数,有些小伙伴说到 Redis持久化 肯定张口就来,毕竟也就 AOF 和 RDB 两个概念,只要你准备了面试,就不会被问的太惨。

但是你是真的懂还是只是为了应付面试而去应付记忆?你知道 AOFRDB 两个词是什么单词的缩写吗?你落地实施过吗?你真以为面试官听不出来你是背题还是实操吗?

如果 4 个问题你中了一半,那不妨往下看看,也许会有些收获,起码答面试题的时候心中有小菜~!

Redis 持久化

什么是Redis持久化?

咱们先别记得往解决方向前行,先明白这道题的意思。

持久化 就是要让数据永久的保存下去。那什么是 Redis 持久化 ?那就是把Redis保存在内存的数据写到磁盘中,防止服务宕机了内存数据丢失问题。那有些小伙伴就说了,那磁盘损坏了,数据怎么持久化?就算多点备份能解决磁盘损坏问题,那如果来个多点丢失怎么整?停住停住,咱们这篇讲的是Redis内存数据->磁盘的持久化问题,可别指望靠这个问题跟面试官扯半个小时~!

咱们这篇从几个点来说明 Redis持久化 问题。

也就三点大的方向,三步走战略解决你的持久化问题。

一、RDB

先来解决开局的问题之一,RDB 是什么单词的全称。RDB(Redis Database Backup file)--- Redis 数据备份文件,也称为 Redis 数据快照。

这个玩意就是用来将内存中的所有数据都记录到磁盘中,当 Redis 实例故障重启后,从磁盘读取快照文件,从而恢复数据。内心狂喜,看来学的第一个概念就可以解决 Redis 持久化问题~

在学 RDB 之前,我们先明白两个核心概念 forkcow,下面我们会解释,这里先卖个关子。

RDB 是 Redis 中默认的持久化机制,按照一定的时间将内存中的数据以快照的方式保存到磁盘中,它会产生一个特殊类型的文件 .rdb 数据文件,同时可以通过配置文件中的 save 参数来定义快照的周期.

我们从配置文件中的两个配置参数入手,首先是 save 配置。

这个指令是由 Redis 主进程来执行RDB,会阻塞所有命令

我们在配置文件中找到有关于 sava 的配置

1、

dbfilename dump.rdb

该配置项的作用便是用来定义 rdb 文件名(需要注意该名称不能定义为路径,只能定义为文件名称)

当我们执行完 save 命令后,便可在 redis 文件夹中看到一个 dump.rdb   文件

2、

save <seconds> <changes>

该配置项的作用是用来定义多长时间内发生多少次变化便会执行 bgsave,如果是 save "" 则表示禁用 RDB

我们接下来打开 save 配置进行测试

dbfilename dump-test.rdb  # 文件名为 dump-test.rdb
save 3600 1  # 在 3600 秒内发生一次更改,便会执行 bgsave

我们通过 redis-cli 进入操作

然后我们退出后便可在当前目录下看到刚刚生成的 dump-test.rdb 文件

说明我们配置是生效的,接着我们直接重启 Redis ,看是否还存在我们刚刚保存的数据

看到我们的数据,就说明 redis 持久化成功了。然后我们把刚刚生成的  dump-test.rdb 文件删除后重启 redis

这可以说明Redis 启动时是靠 .rdb 来恢复文件数据的。那我们上面一直说到的 bgsave,那 bgsave 又是如何执行的呢?

我们在前面有说过两个概念 forkcow,不知道是否还有印象,这两个概念便是关键~!

bgsave 开始的时候会 fork 主进程得到一个新的子进程,而 子进程共享 主进程的内存数据的。子进程会将数据写到磁盘上的一个临时的 .rdb 文件中,当子进程写完临时文件后,会将原来的 .rdb文件替换掉。这个就是 fork 的核心,那什么是 cow 呢?cow 全称 copy-on-write 技术,当主进程执行读操作的时候是访问共享内存的,而主进程执行写操作的时候,则会拷贝一份数据,执行写操作。

具体流程如下:

这种持久化方式有什么优点呢?

  • 方便持久化,只有一个 dump.rdb 文件

  • 容灾性好,可以将文件保存到安全的磁盘中

  • 性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,将 IO 最大化,保证 Redis 的高性能

缺点也是有的:

  • 数据安全性低,RDB 是间隔一段时间来持久化 (save) ,如果持久化期间 Redis 发生故障,那么就会造成数据丢失,所以这种方式适用于数据要求不是很严谨的情况下使用

  • 保存时间长,如果数据量很大,保存快照的时间就会很长,会占用磁盘空间

优劣均沾,斟酌使用

点击关注公众号,Java干货及时送达

二、AOF

AOF 全称 Append Only File (追加文件)。作用便是 Redis 处理的每一个写命令都会记录在 AOF 文件中,可以看做是命令日志文件。

该功能默认是关闭的,我们可以在 redis.conf 文件中查看有关于 AOF 相关的配置项

1、

appendonly yes   # 开启 AOF 日志记录功能,默认是关闭的

2、

appendfilename "appendonly.aof"  # AOF 文件的名称

以上两个配置项便是用来开启 AOF 日志记录,那么还有个额外的配置项也需要了解

3、

appendfsync everysec   # AOF 命令记录的频率

该配置项有三个可选值

配置项刷盘时机优点缺点
Always同步刷盘可靠性高,几乎不会丢失数据性能影响较大
everysec每秒刷盘性能适中最多丢失1秒的数据
no操作系统控制性能最好可靠性较差,可能丢失大量的数据

有了解 Mysqlrelay log 日志的同学,就不会对这种模型很陌生。

原理:它是将写命令追加到 AOF 文件的末尾,使用 AOF 持久化需要设置同步选项,从而确保写命令同步到磁盘文件上的时机,这是因为对文件进行写入并不会马上将内存同步到磁盘上,而是先存储到缓存区中,然后由操作系统决定什么时候同步到磁盘。

我们开启 AOF 记录功能查看下:

可以看出我们的每一个操作都已经记录到 AOF 文件中,我们这边通过重启 Redis 也一样能获取到刚刚存储的数据,说明持久化是有生效的~

如果你还在到处找面试题,不如上这个Java面试库面试小程序。

我们看到上面的 AOF 记录文件是不是觉得很规整?但是在线上环境中越规整反而不好,因为这文件主要是给机器看的,而不是跟我们看的,因此我们最好能够进行压缩。

为了解决AOF文件体积不断增大的问题,用户可以向Redis发送 bgrewriteaof命令,这个命令会通过 通过移除AOF文件中的冗余命令 来重写(rewrite)AOF文件,使AOF文件的体积变得尽可能地小。bgrewriteaof的工作原理和 bgsave 创建快照的工作原理非常相似:Redis会创建一个子进程,然后由子进程负责对AOF文件进行重写。因为AOF文件重写也需要用到子进程,所以快照持久化因为创建子进程而导致的性能问题和内存占用问题,在AOF持久化中也同样存在。

既然存在手动触发压缩,那也存在自动触发压缩,这就得说到配置文件中的两个配置项

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

该配置项的意思为当AOF文件的体积大于64MB,并且AOF文件的体积比上一次重写之后的体积大了至少一倍(100%)的时候,Redis将执行bgrewriteaof命令。

总结下,它的优点如下:

  • 数据安全。AOF 持久化可以配置 appendfsync 属性中的 always,每进行一次写命令操作就会记录到 AOF 文件中一次

  • 一致性。通过 append 模型写文件,即使中途服务器宕机,也可以通过 redis-check-aof 工具来解决数据一致性问题

缺点如下:

  • AOF 文件比 RDB 文件大,而且恢复速度慢

  • 数据集大的时候比 RDB 文件启动效率低

同样是优劣均沾,斟酌使用

三、两者区别

分别介绍了两者,我们回顾一下两者有什么区别?

方面RDBAOF
持久化方式定时对整个内存做快照记录每一次执行的命令
数据完整性不完整,两次备份之间会丢失相对完整。取决于刷盘策略
文件大小会有压缩,文件体积小记录命令,文件体积很大
宕机恢复速度很快
数据恢复优先级低,因为数据完整性不如AOF高,因为数据完整性更高
系统资源占用高,大量CPU和内存消耗低,主要是磁盘IO资源。且 AOF 重写时会占用大量CPU和内存资源
使用场景可以容忍数分钟的数据丢失,追求更快的启动速度对数据安全性要求较高

看完上面后,想必对两种持久化机制都有一定的了解了。两者都有优劣势,那我们该如何选择?这里给出几点意见~

  1. 如果可以忍受一小段时间内的数据丢失,可以使用 RDB  机制,定时生成 RDB 快照, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快

  2. 但是如果单单使用 RDB 机制,可能导致丢失很多数据,因此我们需要综合使用 AOFRDB 两种持久化机制,用 AOF 来保证数据不丢失,作为数据恢复的第一选择;用 RDB 来做不同程度的冷备份,在 AOF 文件都丢失或损坏不可用的情况下,可以使用 RDB 来进行快速的数据恢复

  3. 我们可以利用 RDB 来快速恢复数据,并用 AOF 来补全数据

我们到这里就讲述了 Redis 持久化机制的配置,通过这篇文章的学习,我相信到时候面试的时候遇到这个问题也不至于那么手足无措~!另外,关注公众号Java技术栈,在后台回复:面试,可以获取我整理的 Java 、Redis 系列面试题和答案,非常齐全。



关注Java技术栈看更多干货

获取 Spring Boot 实战笔记!

以上是关于Redis持久化策略(看这篇,你肯定会有所获)的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Redis 更持久?本文教你!

2021最新华为Java校招面试题,看这一篇就够了!

redis持久化策略

没看这篇干货,别说你会使用“缓存”

Python 3 入门,看这篇就够了!数万字长文!保证你肯定能学会!

如何保证Redis性能与安全?看这篇Redis数据库性能测试及安全优化配置指南就够了