来源 |码猿技术专栏

责编 | Carol

头图 | CSDN 下载自视觉中国

Redis目前已经成为主流的内存数据库了,但是大部分人仅仅是停留在会用的阶段,你真的了解Redis内部的工作原理吗?

今天这篇文章将为大家介绍Redis持久化的两种方案,文章将会从以下五个方面介绍:

  1. 什么是RDB,RDB如何实现持久化?

  2. 什么是AOF,AOF如何实现持久化?

  3. AOF和RDB的区别。

  4. 如何重启恢复数据?

  5. 持久化性能问题和解决方案

RDB

RDB持久化是把当前进程数据生成快照保存到硬盘的过程, 触发RDB持久化过程分为手动触发和自动触发。

RDB完成后会自动生成一个文件,保存在dir配置的指定目录下,文件名是dbfileName指定。

Redis默认会采用LZF算法对生成的RDB文件做压缩处理,压缩后的文件远远小于内存大小,默认开启。

手动触发

  • 手动触发的命令有savebgsave

  • save:该命令会阻塞Redis服务器,直到RDB的过程完成,已经被废弃,因此线上不建议使用。

  • bgsave:每次进行RDB过程都会fork一个子进程,由子进程完成RDB的操作,因此阻塞只会发生在fork阶段,一般时间很短。

自动触发

  • 除了手动触发RDB,Redis服务器内部还有如下几个场景能够自动触发RDB:

  1. 根据我们的 save m n 配置规则自动触发。

  2. 如果从节点执行全量复制操作, 主节点自动执行bgsave生成RDB文件并发送给从节点。

  3. 执行debug reload命令重新加载Redis时, 也会自动触发save操作。

  4. 默认情况下执行shutdown命令时, 如果没有开启AOF持久化功能则自动执行bgsave

RDB执行流程

  • RDB的主流方式就是bgsave,通过下图我们来看看RDB的执行流程:

  • 通过上图可以很清楚RDB的执行流程,如下:

  1. 执行bgsave命令后,会先判断是否存在AOF或者RDB的子进程,如果存在,直接返回。

  2. 父进程fork操作创建一个子进程,fork操作中父进程会被阻塞。

  3. fork完成后,子进程开始根据父进程的内存生成临时快照文件,完成后对原有的RDB文件进行替换。执行lastsave命令可以查看最近一次的RDB时间。

  4. 子进程完成后发送信号给父进程,父进程更新统计信息。

RDB的优点

  • RDB是一个紧凑压缩的二进制文件, 代表Redis在某个时间点上的数据快照。非常适用于备份, 全量复制等场景。比如每6小时执行bgsave备份,并把RDB文件拷贝到远程机器或者文件系统中,用于灾难恢复。

  • Redis加载RDB恢复数据远远快于AOF的方式。

RDB的缺点

  • RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行fork操作创建子进程,属于重量级操作,频繁执行成本过高。

  • RDB文件使用特定二进制格式保存, Redis版本演进过程中有多个格式的RDB版本, 存在老版本Redis服务无法兼容新版RDB格式的问题。

AOF

  • AOF(append only file) 持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性, 目前已经是Redis持久化的主流方式

如何开启AOF

  • 开启AOF功能需要设置配置:appendonly yes, 默认不开启。AOF文件名通过appendfilename配置设置, 默认文件名是appendonly.aof。保存路径同RDB持久化方式一致,通过dir配置指定。

AOF整体的执行流程

  • AOF执行的流程大致分为命令写入文件同步文件重写重启加载四个步骤,如下图:

  • 从上图大致了解了AOF的执行流程,下面一一分析上述的四个步骤。

命令写入

  • AOF命令写入的内容直接是文本协议格式。例如set hello world这条命 令, 在AOF缓冲区会追加如下文本:

*3\r\n$3\r\nset\r\n$5\r\nhello\r\n$5\r\nworld\r\n
  • 命令写入是直接写入到AOF的缓冲区中,至于为什么?原因很简单,Redis使用单线程响应命令,如果每次写AOF文件命令都直接追加到硬盘, 那么性能完全取决于当前硬盘负载。先写入缓冲区aof_buf中, 还有另一个好处, Redis可以提供多种缓冲区 同步硬盘的策略,在性能和安全性方面做出平衡。

文件同步

  • Redis提供了多种AOF缓冲区同步文件策略, 由参数appendfsync控制,如下:

    • 配置为always时, 每次写入都要同步AOF文件, 在一般的SATA硬盘上,Redis只能支持大约几百TPS写入, 显然跟Redis高性能特性背道而驰,不建议配置。

    • 配置为no,由于操作系统每次同步AOF文件的周期不可控,而且会加大每次同步硬盘的数据量,虽然提升了性能,但数据安全性无法保证。

    • 配置为everysec(默认的配置),是建议的同步策略, 也是默认配置,做到兼顾性能和数据安全性。理论上只有在系统突然宕机的情况下丢失1秒的数据(当然,这是不太准确的)。

文件重写机制

  • 随着命令不断写入AOF, 文件会越来越大, 为了解决这个问题, Redis引入AOF重写机制压缩文件体积。AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程。

  • 为什么要文件重写呢? 因为文件重写能够使得AOF文件的体积变得更小,从而使得可以更快的被Redis加载。

  • 重写过程分为手动触发和自动触发。

    • 手动触发直接使用bgrewriteaof命令。

    • 根据auto-aof-rewrite-min-sizeauto-aof-rewrite-percentage参数确定自动触发时机。

  • auto-aof-rewrite-min-size:表示运行AOF重写时文件最小体积, 默认为64MB。

  • auto-aof-rewrite-percentage:代表当前AOF文件空间(aof_current_size) 和上一次重写后AOF文件空间(aof_base_size) 的比值。

  • 自动触发时机相当于aof_current_size>auto-aof-rewrite-minsize&&(aof_current_size-aof_base_size) /aof_base_size>=auto-aof-rewritepercentage。其中aof_current_sizeaof_base_size可以在info Persistence统计信息中查看。

  • 那么文件重写后的AOF文件为什么会变小呢? 有如下几个原因:

  1. 进程内已经超时的数据将不会再次写入AOF文件中。

  2. 旧的AOF文件含有无效命令,如del key1、 hdel key2等。重写使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令。

  3. 多条写命令可以合并为一个, 如:lpush list a、 lpush list blpush listc可以转化为:lpush list a b c。为了防止单条命令过大造成客户端缓冲区溢出,对于list、 set、 hash、 zset等类型操作,以64个元素为界拆分为多条。

  • 介绍了文件重写的系列知识,下面来看看Redis内部是如何进行文件重写的,如下图:

    • 看完上图,大致了解了文件重写的流程,对于重写的流程,补充如下:

    1. 重写期间,主线程并没有阻塞,而是在执行其他的操作命令,依然会向旧的AOF文件写入数据,这样能够保证备份的最终完整性,如果数据重写失败,也能保证数据不会丢失。

    2. 为了把重写期间响应的写入信息也写入到新的文件中,因此也会为子进程保留一个缓冲区,防止新写的文件丢失数据。

    3. 重写是直接把当前内存的数据生成对应命令,并不需要读取老的AOF文件进行分析、命令合并。

    4. AOF文件直接采用的文本协议,主要是兼容性好、追加方便、可读性高可认为修改修复。

    5. 无论是RDB还是AOF都是先写入一个临时文件,然后通过重命名完成文件的替换。

    AOF的优点

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

    AOF的缺点

    • 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB。在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间。

    • 数据恢复速度相对于RDB比较慢。

    AOF和RDB的区别

    RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。

    AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。

    重启加载

    无论是RDB还是AOF都可用于服务器重启时的数据恢复,执行流程如下图:

    上图很清晰的分析了Redis启动恢复数据的流程,先检查AOF文件是否开启,文件是否存在,再检查RDB是否开启,文件是否存在。

    性能问题与解决方案

    通过上面的分析,我们都知道RDB的快照、AOF的重写都需要fork,这是一个重量级操作,会对Redis造成阻塞。因此为了不影响Redis主进程响应,我们需要尽可能降低阻塞。

    那么如何减少fork操作的阻塞呢?

    1. 优先使用物理机或者高效支持fork操作的虚拟化技术。

    2. 控制Redis实例最大可用内存, fork耗时跟内存量成正比, 线上建议每个Redis实例内存控制在10GB以内。

    3. 合理配置Linux内存分配策略,避免物理内存不足导致fork失败。

    4. 降低fork操作的频率,如适度放宽AOF自动触发时机,避免不必要的全量复制等。

    总结

    本文介绍了Redis持久化的两种不同的策略,大部分内容是运维人员需要掌握的,当然作为后端人员也是需要了解一下,毕竟小公司都是一人搞全栈,哈哈。

    推荐阅读

    • 如何保证 HBase 服务的高可用?看看这份 HBase 可用性分析与高可用实践吧!

    • 一文带你认识keepalived,再带你通关LVS+Keepalived!

    • 那个分分钟处理 10 亿节点图计算的 Plato,现在怎么样了?

    • “谷歌杀手”发明者,科学天才 Wolfram

    • 数据库激荡 40 年,深入解析 PostgreSQL、NewSQL 演进历程

    • 超详细!一文告诉你 SparkStreaming 如何整合 Kafka !附代码可实践

    • 5分钟!就能学会以太坊 JSON API 基础知识!

      真香,朕在看了!

天天用Redis,持久化方案你又知道哪些?相关推荐

  1. (转)淘淘商城系列——Redis持久化方案

    http://blog.csdn.net/yerenyuan_pku/article/details/72858975 Redis中设置key的过期时间 Redis中的expire命令用于设置key的 ...

  2. 淘淘商城——Redis持久化方案

    Redis中设置key的过期时间 Redis中的expire命令用于设置key的过期时间,以毫秒计.key过期后将不再可用.Redis中的expire命令基本语法如下: expire key seco ...

  3. redis持久化方案

    说到redis的持久化,可以先说redis的高可用,而保证其高可用的手段有------持久化.复制.哨兵.集群. 持久化:数据的备份,将数据存入硬盘保证数据不会因进程退出而丢失. 复制:是哨兵和集群的 ...

  4. redis持久化方案比较

    redis持久化包括rdb和aof两种方案 1.rdb持久化方案 持久化过程:按照redis.conf文件配置,如 save 900 1 save 300 10 save 60 10000 ,在指定时 ...

  5. redis数据丢失_有效避免数据丢失!Redis持久化方案选择详解

    为什么需要持久化呢? 通常情况下redis的数据全部存储在内存中,数据库一旦故障发生重启数据会全部丢失,即使是在redis cluster或者redis sentinel模式下主从同步数据的恢复仍然需 ...

  6. Redis持久化 RDB和AOF 比较与选择

    Redis持久化方案 Redis是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘.当下次Redis重启时,利 ...

  7. 【腾讯阿里最全面试题】Redis持久化RDB和AOF 的区别

    跳槽必备: 嵌入式开发转互联网开发面经分享:嵌入式开发成功转战互联网行业 大厂offer的前置条件 学校学历,技术水准分析:大厂必备前置条件,项目经验 腾讯T9(原T3.1)offer,"8 ...

  8. Redis 的持久化方案

    目录 文章目录 目录 RDB 触发 RDB 持久化 RDB 执行流程 RDB 常用配置 AOF AOF 执行流程 命令写入 文件同步 文件重写 重启加载 AOF 常用配置 性能问题与解决方案 Redi ...

  9. redis持久化到mysql的方案_redis进阶: 数据持久化

    redis是内存数据库,即数据库状态都是存储于内存中,因此,当服务器重启或者断开后,数据便会丢失:为了解决数据丢失问题,便需要将数据从内存保持到磁盘中,这就是redis的数据持久化 目前,redis实 ...

最新文章

  1. 宝塔面板搭载ThinkPHP5.0项目关于open_basedir报错解决办法
  2. linux 安装软件的几种方法
  3. 身价超13000亿!他又重回世界首富了
  4. hdu 1284 钱币兑换问题
  5. Qualcomm 3D音频插件学习
  6. 金字塔原理——表达的逻辑
  7. 系统分析师 考试大纲
  8. 凯恩帝k1000ti参数设置_凯恩帝K1000T系统用户手册.pdf
  9. AcGiGeometry::text 自画实体输出文字实例
  10. JS仿iGoogle自定义首页模块拖拽效…
  11. 浏览器网络异常导致JS文件请求失败的问题及处理
  12. Tensorflow serving 学习(一)
  13. 世界上最强大的两个字母的单词
  14. winform工具1-图片去除水印
  15. MySQL数据库——语句
  16. App运营:怎么提升App下载安装量?
  17. 计算机仿真题液相色谱,毛细管电泳分离过程计算机仿真研究.pdf
  18. 【观察】 2016年度中国企业级市场十大新闻
  19. gt-itm模型生成拓扑结构
  20. 海报的5种处理方式,让你的照片更吸睛

热门文章

  1. java gzipoutputstream_java – GZIPInputStream逐行读取
  2. python教材答案第六章_python第六章{输入和输出}
  3. rust里mp5a4_Rust源码分析:channel内部mpsc队列
  4. linux进程管理子系统分析,linux进程管理子系统简要分析
  5. oracle 主键约束重名,主键及主键索引的关系及相互影响
  6. 大离谱!论文“撞衫”,11篇不同高校论文中竟出现同一块桌布....
  7. 本科生获42万元奖学金!培养拔尖人才,这所高校动真格!
  8. 怎么判断自己适不适合读博士?
  9. 31省份开学时间一览表
  10. 复杂网络研究:让世界变得简单