在本文中,我们将学习以下案例:
1、使用RDB
2、使用AOF
3、RDB 和 AOF 的结合使用
概要
由于redis是在内存中储存数据的,所以当linux服务器重新启动后,所有数据都将丢失(重启redis不会是因为redis默认开启了RDB保存了一份dump.rdb,每次启动redis,则会加载rdb文件进行数据恢复)。
为了保证数据的安全,redis提供了将数据持久化到硬盘的机制。redis共有两种数据持久化类型:RDB和AOF。RDB可以看作是redis在某个时间点的快照,非常适合永远备份和灾难恢复。AOF则是一个写入操作的日志,将在服务器启动时被重放。
一、使用RDB
对于一个像redis这样的内存数据存储,启用持久化功能是防止数据丢失的最好方法,实现持久化的一种显而易见的方法是不断的对存储数据的内存进行快照,而这基本上正式redis的RDB的工作方式,下面介绍如何配置RDB持久化功能,并了解有关快照执行过程的更多细节。
1.1 操作步骤:
1、调用config set命令,在一个正在运行的redis实例上启用rdb持久化:
2、如果要永久性的启用RDB持久化,可以在redis配置文件中设置save参数:
3、如果需要在一个运行的redis实例上就用RDB持久化,可以直接通过redis-cli设置save参数为空字符串:bin/redis-cli config set save ""
4、要永久禁用RDB持久化,则可以在redis.conf配置文件中注释/删除掉save参数
5、通过redis-cli获取RDB是否开启:bin/redis-cli config get save 。如果save选项为一个空字符串则表示RDB是被禁用的。否则,则返回RDB快照的触发策略,RDB的快照策略格式为x1,y1,x2,y2....,其中含义是,如果超过y个key发生了改变,且此时没有转储正在发生,则在x秒后进行数据转储。
6、RDB文件默认文件名称为:dump.rdb
7、如果需要手动执行RDB快照,在redis-cli中调用save命令即可,redis-cli客户端将会被阻塞一段时间,然后命令提示符会返回如下内容:
8、或者我们可以调用BGSAVE的命令来执行非阻塞的RDB转储,可以通过ps -ef|grep redis命令查看转储进程的pid。
9、 通过redis-cli 执行 info persistence命令可以获取到与持久化相关的指标与状态:
1.2、工作原理
RDB默认为开启,当设置config set save "900 1" 表示如果有超过1个键发生了改变,则在900秒后进行数据转储,在save选项中,我们可以配置多个策略来控制RDB快照文件的频率。
通过save/bgsave命令可以手动启动一次RDB转储,这两个命令的不同之处在于,save使用的是主线程进行同步存储,会阻塞redis服务器。bgsave则是在后台开启一个子进程进行数据转储。所以一般建议永远不要在生产环境使用save,除非是凌晨停机状态。
bgsave由于是异步的,它不会阻塞主进程继续收集请求,它会在通过fork()系统调用创建一个子进程将数据转储保存在一个名为temp-<bgsave-pid>. rdb的临时文件中。当转储过程结束后,这个临时文件会被重命名为由参数dbfilename定义的名字覆盖并保存在dire指定的本地目录中。上述两个参数都可以通过redis-cli进行动态修改。
在子进程替换旧转储文件后,它会根据子进程使用的私有数据量输出一条日志:
我们还可以通过info persistence命令可以获取到与持久化相关的指标与状态:
rdb_bgsave_in_progress:1 表示转储正在进行
rdb_last_bgsave_time_sec的值表示当前正在进行的bgsave命令所持续的时间
rdb_last_save_time:1543846365 表示最后一次成功的时间戳
1.3、更多细节
下面是一些与RDB持久化相关的一些配置选项,建议全部使用默认值(yes:
1、stop-writes-on-bgsave-error yes:如果该选项设置为yes的化,那么作为保护机制,当bgsave失败时,redis服务器将停止接收写入操作。
2、rdbcompression yes:压缩可以显著的减少转储文件的大小,但是会占用消耗更多的CPU
3、rdbchecksum yes:在快照文件的末尾创建一个CRC64的校验和。使用该选项将在保存时加载快照文件时额外的消耗约10%的性能,如果设置为no可以获得最大的性能,但同时会降低对数据损坏的抵抗力。
4、由于save/bgsave 命令生成的转储文件可以用作数据备份文件,我们可以使用linux系统中的crontab定期将RDB文件复制到本地目录,供日后恢复使用
5、如果要还原RDB快照,我们需要把快照文件复制到dir选项指定的位置。
二、使用AOF
在上述案例当中,我们学习了RDB的方式进行数据持久化,但RDB做数据持久化并不能提供非常强的一致性,AOF(append-only file)是一种只记录redis写入命令的追加式日志文件。因为每个写入命令都会被追加到AOF文件中,所以AOF的数据一致性比RDB更高,在下面我们开始展示如何在redis中使用AOF进行数据持久化,并介绍一些重要的配置参数。
2.1 操作步骤
1:使用config set命令,对一个正在运行的redis实例上启用AOF持久化:
2:如果想要永久的启动AOF持久化,可以在redis配置文件中添加appendonly yes,然后重新启动redis服务:
3::要在一个正在运行的redis实例中,禁用AOF持久化,可以把appendonly 设置为no,然后重新启动redis。
4:要永久的禁用AOF持久化,则修改配置文件redis.conf中appendonly no 并重新启动redis服务即可。
5:使用info persistence命令检查AOF相关的内容判断是否启用AOF功能
6:AOF文件名默认保存为appendonly.aof
2.2 工作原理
当AOF功能被启用时,redis将会在数据目录创建AOF文件,AOF文件名默认保存为appendonly.aof,并可以通过配置文件中appendonlyfilename 参数进行修改。同时redis还会将当前内存的数据填充到这个AOF文件中来。
每当redis接收到会实际修改内存数据的写入命令时,redis会将该命令追加到aof文件中,如果深入研究AOF的写入过程,就会发现操作系统实际上维护了一个缓冲区,redis的命令首先会被写入到这个缓冲区当中,而缓冲区的数据必须被刷新到磁盘当中才能永久保存。这个过程是通过linux系统调用fsync()完成的,这是一个阻塞调用,只有磁盘设备报告缓冲区中的数据写入完成后才会返回。
在将命令追加到AOF文件时候,我们可以通过配置redis的参数appendfsync来调整调用fsync的频率,该参数共有三个选项:
1、always:对每个写入的命令都调用fsync,这个选项可以确保redis服务器发生意外崩溃或硬件故障时,只会丢失一个命令,但是由于fsync是一个阻塞调用,redis的性能会收到物理磁盘写入性能的限制,所以此举是不明智的,redis的性能会显著降低!
2、everysec:每秒调用一次fsync,采用这一选项时,在意外灾难事件中只会有一秒钟的数据会被丢失。
3、no永远不调用fsync,采用该选项时,将由操作系统决定何时把数据从缓冲区写入到磁盘,大多数linux系统中,这个频率是每30s。
在redis服务器关闭时,fsync都会显式的被调用,以确保吸入缓冲区的数据都会被刷新在磁盘当中。当redis启动时,AOF文件都会被用来恢复数据
2.3 更多细节
随着redis将写入命令不断的追加到AOF文件当中,aof文件的大小会显著的增加,这回拖慢redis启动时的数据重建过程,redis提供了一种机制,即通过AOF重写要压缩AOF文件,redis主进程会创建一个子进程来执行AOF的重写,这个子进程会创建一个新的AOF文件来存储重写的结果,父进程则继续相应请求并将命令追加到旧的AOF文件当中,这里不讲述AOF重写的过程细节。
三、使用RDB+AOF结合使用
在涉及到数据持久化时,我们总是需要考虑几个因素:意外停机导致数据丢失、保存数据时的性能开销、持久化文件的大小以及数据恢复的速度。对于RDB而言,两次快照之间写入的数据可能会丢失,当写入流量较大且数据集也很大时,RBD中系统调用fork()的延迟和内存开销也可能变成一个问题。不过,与AOF相比,RDB转储文件占用的硬盘空间更少,并且从RDB转储中恢复数据的速度更快。事实上,我们可以同时启用这两个功能。
同时开启RDB跟AOF,我们会发现数据同时以RDB和AOF的方式保存到了redis的数据目录,并且可以清楚的发现AOF文件要比RDB文件更大。
在同时开启RBD和AOF后,我们将配置参数aof-use-rdb-preamble设置为yes,来启用4.x 开始提供的新的混合持久化功能。这里建议在redis4.x之后启用AOF和混合持久化,如果我们能够忍受某些可能的数据丢失,那么只使用RDB能够获得更好的性能。
最后,redis保证RDB转储跟AOF重写不会同时进行。当redis启动时,即便RDB和AOF持久化同时启用且AOF,RDB文件都存在,则redis总是会先加载AOF文件,这是因为AOF文件被认为能够更好的数据一致性,当家宅AOF文件时,如果启用了混合持久化,那么redis将首先检查AOF的前五个字符,如果这五个字符是REDIS,那么该AOF文件就是混合格式的,redis服务器会先加载RDB部分,然后再加载AOF部分。
以上参考:《Redis 4.x Cookbook》持久化。
三千多字,我滴妈呀!!!!!