新手村:Redis进阶篇二---持久化

2024-02-12 15:20

本文主要是介绍新手村:Redis进阶篇二---持久化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


1. 简介

持久化即将数据保存到可永久保存的存储设备中。我们知道 Redis 为了保证效率而把数据都缓存在内存中,但当我们重启系统或关闭系统后,缓存在内存中的数据都会消失,所以为了让有些数据能保留下,Redis 持久化存储就应运而生。Redis 提供了两种方式进行持久化,一种是RDB 持久化,另一种是 AOF(append only file) 持久化,下面我们逐一介绍。

2. RDB 持久化

RDB 是 Redis 默认的持久化机制,它的工作原理是把当前内存中的数据生成快照 (snapshot) 的方式写入磁盘中的二进制文件中,默认的文件名为 dump.rdb。恢复时将快照文件直接读到内存中。RDB 有两种触发方式,分别是自动触发和手动触发。

2.1 自动触发

自动触发使用 save 相关配置触发,比如 “save m n”,表示在 m 秒内数据库存在 n 次修改时,自动触发BGSAVE (BGSAVE 命令在手动触发时会介绍)。Redis 默认配置如下:

save 900 1      # 在 900 秒内如果至少有 1 个 key 的值变化,则触发
save 300 10     # 在 300 秒内如果至少有 10 个 key 的值变化,则触发
save 60 10000   # 在 60 秒内如果至少有 10000 个 key 的值变化,则触发

当实际操作满足配置的 save 形式时就会进行 RDB 持久化,将当前的数据快照保存。

2.2 手动触发

手动触发进行 RDB 持久化涉及到两个 Redis 服务器命令:

  1. SAVE:执行一个同步保存操作,将当前 Redis 实例的所有数据快照以 RDB 文件的形式保存到磁盘中。

  2. BGSAVE:用于在后台异步保存当前数据库的数据到磁盘。

SAVE 命令由于是同步操作,因此会阻塞当前 Redis 服务器知道 RDB 持久化过程完成为止,对于内存比较大的实例会造成长时间阻塞,不建议在线上环境使用。BGSAVE 命令会执行 fork 操作创建一个子进程,由子进程完成 RDB 持久化过程,完成后自动结束,阻塞只发生在 fork 过程,一般时间很短。基本上 Redis 内部的 RDB 操作都是采用 BGSAVE  命令。

2.3 RDB 优缺点

RDB 的优点:

  • RDB 文件是一个紧凑压缩的二进制文件,它保存了 Redis 在某个时间点的数据,比较适合进行备份和灾难恢复。

  • 生成 RDB 文件的过程是由父进程 fork 操作创建的一个子进程完成,父进程仍然可以接受其他命令请求,不用进行任何磁盘 IO 操作。

  • 由于 RDB 文件是二进制文件,因此在恢复数据集时速度更快。

RDB 的缺点:

  • RDB 无法做到实时持久化/秒级持久化。因为 BGSAVE 命令需要执行 fork 操作创建子进程,如果频繁操作必然会占用大量内存,执行成本过高,反而使性能降低。

  • RDB 文件使用特定二进制格式保存,Redis 版本演进过程中有多个格式的 RDB 版本,容易出现版本不兼容问题。

  • RDB 是隔一段时间进行备份,如果 Redis 在备份时出现意外宕机,那么就会失去最后一次快照的数据。

3. AOF 持久化

差别于通过保存数据库中的键值对的 RDB 持久化方式,AOF 持久化是通过保存 Redis 服务器所执行的写命令来记录数据库状态,重启时再重新执行 AOF 文件中的命令以完成数据恢复。AOF 的主要作用是解决了数据持久化的实时性,目前已经是 Redis 持久化的主流方式。

3.1 使用 AOF

Redis 中 AOF 是默认关闭的,使用前要将配置参数 appendonly 改为 yes(5.3 中会涉及一些配置参数,配置文件是安装目录下的 redis.windows.conf,参数在 APPEND ONLY FILE 一栏)。AOF 文件的保存文件名通过参数 appendfilename 参数配置,默认是 appendonly.aof。AOF 持久化策略的选择由 appendfsync 参数进行选择,有下面几种:

  • no:不执行 fsync,由操作系统保证数据同步到磁盘,速度快但不安全。

  • always:每次写入都执行 fsync,虽然保证数据同步到磁盘,但是效率很低。

  • everysec:默认配置,每秒执行一次 fsync,可能会丢失这 1 秒的数据,但兼顾了安全性和效率,最常用的选择。

3.2 AOF工作流程

AOF 的工作流程操作:命令写入 (append)、文件同步 (sync)、文件重写 (rewrite)、重启加载 (load)。首先,所有的写入命令都会被追加到 AOF 缓冲区中,然后 AOF 缓冲区根据对应的持久化策略对磁盘进行文件同步操作。当 AOF 文件的大小超过所设定的重写阈值时对 AOF 文件进行重写。当需要重写时,父进程会进行 fork 操作创建一个子进程,子进程带有父进程的数据副本,由子进程完成重写过程,在此期间父进程仍然可以处理其他命令。当我们重启 Redis 服务器时,可以加载 AOF 文件进行数据恢复,流程如下:

持久化

从上图我们也可以得知,在同时开启了 RDB 和 AOF 的情况下,Redis 会优先 AOF 文件的加载。遇到异常时,可以使用修复命令 redis-check-aof--fix 进行修复。在上述流程中,我们有几点需要注意与知晓的:

  1. 为什么需要 AOF 缓冲:由于 Redis 本身是单线程工作的,如果每次都直接把写入命令追加到 AOF 文件中,那么此时的性能取决于磁盘的 IO 性能,会降低性能。先写入 AOF 缓冲区中,我们还可以选择缓冲区同步到磁盘的策略,进一步兼顾安全性和性能。

  2. 为什么需要 AOF 重写:由于 AOF 持久化是不断将写命令记录到 AOF 文件中,随着时间的推移,文件必然会越来越大,这样会增加恢复时的压力。除此之外,例如一个 key 表示粉丝数,增加粉丝的过程我们会使用大量自增命令,而实际上在恢复时我们只需要知道在这段时间内总共增加了多少即可。这个例子也正指明了重写机制的工作原理:AOF 文件重写并非是对原文件进行整理,而是直接读取服务器中现有的键值对,然后用一条命令代替记录中改键值对的多条命令操作,生成一个新的文件替换原文件

  3. AOF 重写触发机制:AOF 重写也分自动触发和手动触发。

  • 自动触发涉及两个配置参数:一个是 auto-aof-rewrite-percent,默认值是 100;另一个是 auto-aof-rewrite-min-size,默认值是 64MB。按照默认配置,Redis 会记录上次重写时 AOF 文件大小,并当目前 AOF 文件是上一次重写后大小的一倍且文件大于 64MB 时自动触发。

    auto-aof-rewrite-percent:当目前 AOF 文件大小超过上一次重写的 AOF 文件大小的百分之几时进行重写。auto-aof-rewrite-min-size:设置允许重写的最小 AOF 文件大小,避免了文件很小却满足百分比要求的重写情况。

  • 手动触发直接调用 BGREWRITEAOF 命令。

3.3 AOF 优缺点

AOF 的优点:

  • 提供了多种同步频率,即使使用默认的同步频率每秒同步一次,Redis 最多也就失去 1 秒的数据。

  • AOF 文件使用 Redis 命令追加的形式来构造,即使只能向 AOF 文件写入命令的片段,也很容易使用redis-check-aof 工具修正。

  • AOF 文件的格式可读性较强,可以为使用者提供更灵活的处理方式。

AOF 的缺点:

  • 在拥有相同数据的情况下,AOF 文件通常会比 RDB 文件体积更大。

  • 当 Redis 负载较高的情况下,RDB 会比 AOD 具有更好的性能保证。

  • RDB 使用快照的形式来持久化整个 Redis 数据,而 AOF 只是将每次执行的命令追加到 AOF 文件中,因此从理论上说,RDB 比 AOF 方式更健壮。官方文档也指出,AOF 的确也存在一些 BUG,这些 BUG 在RDB 没有存在。

4. 如何选择

介绍了 Redis 持久化的两种方式,那么我们在实际中应该如何选择呢?对于数据库而言,数据是相当重要的,RDB 相比于 AOF 而言出现异常丢失数据可能会更严重,除此之外,选择 RDB 是更好的,定时生成快照是常用的数据库备份方式,并且 RDB 文件是二进制文件,在恢复数据集时速度更快,使用 RDB 方式也可以规避 AOF 方式中的一些隐藏 bug。但是在一般情况下,我们应该同时开启两种持久化方式,而不是单独使用某一种持久化机制。由于通常情况下 AOF 方式保存的数据更具实时性且更完整,因此相比 RDB 文件,Redis 重启时会优先使用 AOF 文件来恢复数据。

 往期精选

新手村:最适合新手的 Redis 基础

新手村:Redis 基础补充知识

新手村:Redis进阶篇一

不甘于「本该如此」,「多选参数 」值得关注

这篇关于新手村:Redis进阶篇二---持久化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/702888

相关文章

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

Redis中使用布隆过滤器解决缓存穿透问题

一、缓存穿透(失效)问题 缓存穿透是指查询一个一定不存在的数据,由于缓存中没有命中,会去数据库中查询,而数据库中也没有该数据,并且每次查询都不会命中缓存,从而每次请求都直接打到了数据库上,这会给数据库带来巨大压力。 二、布隆过滤器原理 布隆过滤器(Bloom Filter)是一种空间效率很高的随机数据结构,它利用多个不同的哈希函数将一个元素映射到一个位数组中的多个位置,并将这些位置的值置

Lua 脚本在 Redis 中执行时的原子性以及与redis的事务的区别

在 Redis 中,Lua 脚本具有原子性是因为 Redis 保证在执行脚本时,脚本中的所有操作都会被当作一个不可分割的整体。具体来说,Redis 使用单线程的执行模型来处理命令,因此当 Lua 脚本在 Redis 中执行时,不会有其他命令打断脚本的执行过程。脚本中的所有操作都将连续执行,直到脚本执行完成后,Redis 才会继续处理其他客户端的请求。 Lua 脚本在 Redis 中原子性的原因

laravel框架实现redis分布式集群原理

在app/config/database.php中配置如下: 'redis' => array('cluster' => true,'default' => array('host' => '172.21.107.247','port' => 6379,),'redis1' => array('host' => '172.21.107.248','port' => 6379,),) 其中cl

Redis的rehash机制

在Redis中,键值对(Key-Value Pair)存储方式是由字典(Dict)保存的,而字典底层是通过哈希表来实现的。通过哈希表中的节点保存字典中的键值对。我们知道当HashMap中由于Hash冲突(负载因子)超过某个阈值时,出于链表性能的考虑,会进行Resize的操作。Redis也一样。 在redis的具体实现中,使用了一种叫做渐进式哈希(rehashing)的机制来提高字典的缩放效率,避

【吊打面试官系列-Redis面试题】说说 Redis 哈希槽的概念?

大家好,我是锋哥。今天分享关于 【说说 Redis 哈希槽的概念?】面试题,希望对大家有帮助; 说说 Redis 哈希槽的概念? Redis 集群没有使用一致性 hash,而是引入了哈希槽的概念,Redis 集群有 16384 个哈希槽,每个 key 通过 CRC16 校验后对 16384 取模来决定放置哪个槽, 集群的每个节点负责一部分 hash 槽。

Redis地理数据类型GEO

通常要计算两个地理位置的距离不是很方便,这里可以直接通过Redis提供的GEO操作来完成地理位置相关的计算 1)添加地理位置 语法:geoadd key longitude latitude member [longitude latitude member] ...字段说明:key:存放地理位置的集合名称longitude:地理坐标的经度latitude:地理坐标的纬度member:表示这

Redis-主从集群

主从架构 单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。 主从数据同步原理 全量同步 主从第一次建立连接时,会执行全量同步,将master节点的所有数据都拷贝给slave节点,流程: 判断是否是第一次同步,如果是,返回版本信息(replication id 和offset),将salve节点的版本信息变为master的

Redis安装使用总结

一、下载安装 从 github 下载:https://github.com/MSOpenTech/redis/releases 或者 https://github.com/ServiceStack/redis-windows 解压缩,如图: 二、配置 打开redis.windows-sevice.conf文件, 2.1 绑定ip:搜索127.0.0.1 ,发现bind 127.0.0.

面对Redis数据量庞大时的应对策略

面对Redis数据量庞大时的应对策略,我们可以从多个维度出发,包括数据分片、内存优化、持久化策略、使用集群、硬件升级、数据淘汰策略、以及数据结构选择等。以下是对这些策略的详细探讨: 一、数据分片(Sharding) 当Redis数据量持续增长,单个实例的处理能力可能达到瓶颈。此时,可以通过数据分片将数据分散存储到多个Redis实例中,以实现水平扩展。分片的主要策略包括: 一致性哈希:使用一