redis是一个内存数据库,数据保存在内存中,但是我们都知道内存中的数据变化很快,容易丢失。幸运的是,Redis还为我们提供了持久化机制,即RDB(RedisDataBase)和AOF(AppendOnlyFile)。这里假设你已经了解了redis的基本语法,某信网站上有很好的教程,你可以去看看。基本使用的文章就不写了,都是常用的命令。下面分别介绍这两种方法。由浅入深。1、持久化过程既然redis数据可以存储在磁盘上,那么这个过程是怎样的呢?有以下五个过程:(1)客户端向服务器发送写操作(数据在客户端的内存中)。(2)数据库服务器收到写请求的数据(数据在服务器的内存中)。(3)服务器调用write系统调用将数据写入磁盘(数据在系统内存的buffer中)。(4)操作系统将缓冲区中的数据传送给磁盘控制器(数据在磁盘缓存中)。(5)磁盘控制器将数据写入磁盘的物理介质(数据实际落在磁盘上)。这5个过程是理想情况下正常的保存过程,但是大多数情况下,我们的机器等都会出现各种故障,这里分两种情况:(1)Redis数据库故障,只要执行上面的第三步就可以了,就可以持久化存储了,剩下的两步都是操作系统帮我们完成的。(2)如果操作系统出现故障,必须完成以上5个步骤。这里我们只考虑保存过程中可能出现的故障。其实保存的数据也有可能被破坏,这就需要一定的恢复机制,这里不展开。现在主要考虑的是redis是如何实现以上五步省盘的。它提供了两种策略机制,分别是RDB和AOF。2、RDB机制RDB实际上是将数据以快照的形式保存在磁盘上。什么是快照?你可以理解为对当前时刻的数据拍照并保存。RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。它也是默认的持久化方法。该方法是将内存中的数据作为快照写入二进制文件。默认文件名为dump.rdb。我们安装好redis之后,所有的配置都在redis.conf文件中,里面存放了RDB和AOF两种持久化机制的各种配置。由于RDB机制是通过生成快照来保存某一时刻的所有数据,所以应该有一个触发机制来实现这个过程。对于RDB,提供了三种机制:save、bgsave和automation。我们来看看1.保存触发方法。此命令将阻止当前的Redis服务器。在save命令执行过程中,Redis无法处理其他命令,直到RDB进程完成。具体过程如下:执行完成后,如果有旧的RDB文件,则将旧的替换为新的。我们的客户可能是几万、几十万,这种方式显然不可取。2、bgsave触发方法执行该命令时,Redis会在后台异步进行快照操作,快照也可以响应客户端请求。具体流程如下:具体操作是Redis进程执行fork操作创建子进程,RDB持久化进程负责子进程,完成后自动结束。阻塞只发生在分叉阶段,一般时间很短。Redis内部的所有RDB操作基本上都使用bgsave命令。3.自动触发自动触发是由我们的配置文件完成的。在redis.conf配置文件中,有如下配置,我们可以设置:①save:这个用来配置触发Redis的RDB持久化条件,即何时将内存中的数据保存到硬盘中。例如,“保存mn”。表示在m秒内对数据集进行n次修改时自动触发bgsave。默认配置如下:#表示如果900秒内至少有1个键值变化,则保存save9001#表示如果300秒内至少有10个键值变化,则保存save30010表示如果至少有10000个键60秒内save6010000的值不需要持久化,所以可以注释掉所有的save行,关闭save功能。②stop-writes-on-bgsave-error:默认值为yes。开启RDB,最后一次后台存数据失败,Redis是否停止接收数据。这将使用户意识到数据没有正确地持久化到磁盘,否则没有人会注意到发生了灾难。如果Redis重启,就可以重新开始接收数据③rdbcompression;默认值为是。对于存储在磁盘上的快照,您可以设置是否进行压缩存储。④rdbchecksum:默认值为yes。存储快照后,我们还可以让redis使用CRC64算法进行数据校验,但是这样会增加10%左右的性能消耗。如果你想获得最大的性能提升,你可以关闭这个功能。⑤dbfilename:设置快照的文件名,默认为dump.rdb⑥dir:设置快照文件的存放路径。该配置项必须是目录,不能是文件名。我们可以修改这些配置来达到我们想要的效果。因为第三种方式是配置,所以对比一下前两种:4、RDB的优缺点①优点(1)RDB文件紧凑,备份完整,非常适合备份和容灾。(2)在生成RDB文件时,redis主进程会fork()一个子进程来处理所有的保存工作,主进程不需要进行任何磁盘IO操作。(3)RDB在恢复大数据集时比AOF快。②.缺点RDB快照是全量备份,存储的是二进制序列化形式的内存数据,存储非常紧凑。当持久化快照时,会启动一个子进程负责快照的持久化。子进程将拥有父进程的内存数据。父进程不会反映子进程的内存修改,所以快照持久化期间修改的数据不会反映出来。被保存,数据可能会丢失。3、AOF机制全量备份总是很耗时的。有时我们会提供更高效的AOF方式。工作机制非常简单。Redis会通过write函数将每条接收到的写命令追加到文件中。通俗的理解就是logging。1.持久化原理他的原理见下图:每当有写命令的时候,直接保存到我们的AOF文件中。2、文件重写原理的AOF方式也带来了另外一个问题。持久化文件会越来越大。为了压缩aof的持久化文件。Redis提供了bgrewriteaof命令。将内存中的数据以命令的形式保存到一个临时文件中,同时会fork出一个新的进程来重写该文件。重写aof文件的操作并不是读取旧的aof文件,而是通过命令将整个内存数据库内容重写到一个新的aof文件中,有点类似于快照。3、AOF也有三种触发机制(1)每次修改总是同步:同步持久化每次发生数据变化,都会立即记录到磁盘中。性能较差但数据完整性更好(2)Synchronizationeverysecond:异步操作,Recordpersecond如果一秒内宕机,就会有数据丢失(3)不同no:从不同步4.优点(1)AOF可以更好的保护数据不丢失。一般AOF每隔1秒就会通过一个后台线程进行fsync操作,最多会丢失1秒的数据。(2)AOF日志文件没有任何磁盘寻址开销,写入性能很高,文件不易损坏。(3)即使AOF日志文件过大,后台rewrite操作也不会影响客户端的读写。(4)AOF日志文件的命令以非常易读的方式记录。这个特性非常适合灾难性误删的紧急恢复。例如,有人不小心用flushall命令清除了所有数据。只要此时后台rewrite还没有发生,就可以马上复制AOF文件,删除最后的flushall命令,放回AOF文件。通过恢复机制,自动恢复所有数据5.缺点(1)对于同一条数据,AOF日志文件通常比RDB数据快照文件大(2)开启AOF后,支持的写QPS会变大高于RDB支持的写QPS低,因为AOF一般配置为每秒fsync日志文件一次。当然,fsync每秒一次性能高。无法恢复完全相同的数据。四、RDB和AOF如何取舍,两者加在一起比较好。因为你了解了两种持久化机制,剩下的就看你自己的需求了。不同需求的选择不一定,但通常是组合使用。有张图总结一下:对比完这些特征,剩下的就看你的了。本文转载自微信公众号“愚公要移山”,可关注下方二维码。转载本文请联系愚公移山公众号。
