一、Redis概述
Redis(Remote Dictionary Server):远程字典服务器,是一个可基于内存亦可持久化的日志型、key-value数据库,Redis支持两种持久化方式RDB和AOF.
二、RDB
2.1、什么是RDB
RDB:Redis DataBase,在指定的时间间隔内将内存中的数据集快照写入到磁盘中,也就是所谓的snapshot,它恢复时是将快照直接读入内存中.
2.2、RDB实现原理
Redis会单独创建(fork)一个子进程来进行持久化,它会将数据写入到一个临时文件中,待持久化过程完成后,再用这个临时文件替换掉上次持久化好的文件,整个过程中主进程是不会进行任何的IO操作的,这样就确保了极高的性能,如果需要进行大规模的数据恢复,并且对数据的完整性不是非常敏感,那么使用RDB方式就要比AOF方式更加的高效,RDB的缺点是最后一次的持久化数据有可能会丢失(最后一次数据未触发RDB持久化策略,也没有手动持久化,然后宕机了,这样最后一次的持久化数据就丢失了).
2.3、fork原理
fork就是复制出一个全新的进程,新进程所有的数据和原进程一模一样,并且是原进程的一个子进程.
2.4、如何触发RDB持久化
1、自动触发
################################ SNAPSHOTTING ################################
#
# Save the DB on disk:
#
# save <seconds> <changes>
#
# Will save the DB if both the given number of seconds and the given
# number of write operations against the DB occurred.
#
# In the example below the behaviour will be to save:
# after 900 sec (15 min) if at least 1 key changed
# after 300 sec (5 min) if at least 10 keys changed
# after 60 sec if at least 10000 keys changed
#
# Note: you can disable saving completely by commenting out all "save" lines.
#
# It is also possible to remove all the previously configured save
# points by adding a save directive with a single empty string argument
# like in the following example:
#
# save "" // 如果你只是想使用Redis的缓存功能,不需要使用持久化,那么你可以注释掉所有的save行,然后只打开 save ""这一行配置,这就代表禁用RDB持久化功能
save 900 1 // 900s内有一个写操作,Redis就会触发RDB持久化,将内存中的数据持久化到磁盘上.
save 300 10 // 300s内有10个写操作,Redis就会触发RDB持久化,将内存中的数据持久化到磁盘上.
save 60 10000 // 60s内有10000个写操作,Redis就会触发RDB持久化,将内存中的数据持久化到磁盘上.
2、手动触发
save:该命令会阻塞当前Redis服务器,执行命令期间Redis不能处理其它命令,直到RDB持久化过程完成为止.
bgsave:为了解决save命令对于内存比较大的实例会造成长时间的阻塞,Redis提供了bgsave命令,执行该命令时,Redis会在后台异步进行快照操作,快照操作的同时还能响应客户端的请求,具体的操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,阻塞只发生在fork阶段,一般持续很短的时间.
flushall:使用该命令也会手动触发RDB持久化,对应的dump.rdb是空的.
-rw-r--r--. 1 root root 92 7月 30 00:24 redis-6379-dump.rdb //dump.rdb的大小为92,代表dump.rdb是一个空文件
shutdown:客户端执行shutdown关闭Redis后台服务
2.5、RDB常用配置详解
#RDB核心规则配置 save <指定时间间隔> <执行指定次数更新操作>,满足条件就将内存中的数据同步到硬盘中.
官方出厂配置默认是:
900秒内有1个更改
300秒内有10个更改
60秒内有10000个更改
如果满足上面设置的触发条件,则将内存中的数据快照写入磁盘.
若不想用RDB方案,可以把 save "" 的注释打开,代表禁用RDB持久化方案.
# save ""
save 900 1 // 900s内如果有一个更改则触发RDB保存,文件名为xxx.dump
save 300 10 // 300s内如果有10个更改,则触发保存
save 60 10000 // 60s内如果有10000个更改则触发保存
#当RDB持久化出现错误后,是否依然继续进行工作
yes:不能进行工作
no:可以继续进行工作
可以通过info中的rdb_last_bgsave_status了解RDB持久化是否有错误
stop-writes-on-bgsave-error yes
#配置存储至本地数据库时是否压缩数据,默认为yes。
Redis采用LZF压缩方式,但占用了一点CPU的时间.若关闭该选项,但会导致数据库文件变的非常巨大.建议开启.
rdbcompression yes
#是否校验rdb文件,从rdb格式的第五个版本开始,在rdb文件的末尾会带上CRC64的校验和.
这样做有利于文件的容错性,但是在保存rdb文件的时候,会有大概10%的性能损耗.
所以如果你追求高性能,可以关闭该配置.
rdbchecksum yes
#指定本地数据库文件名,一般采用默认的dump.rdb
dbfilename dump.rdb
#数据目录,数据库的写入会在这个目录.rdb、aof文件也会写在这个目录.
例如 dir配置为./ dbfilename配置为dump.rdb,那么你的持久化数据保存在 ./dump.rdb路径下
例如 dir配置为/opt/myredis/var dbfilename配置为dump6379.rdb那么redis使用rdb持久化的数据保存在
/opt/myredis/var/dump6379.rdb路径下.
dir ./
三、AOF
3.1、什么是AOF
AOF:Append Only File,以日志的形式记录每一个写操作,将Redis执行过的所有写指令记录下来(读指令不记录),只允许追加文件但是不能改写文件,Redis启动之初会读取该文件然后重新构建数据,换言之,Redis重启就是根据日志文件的内容将所有的写指令重新执行一次,以完成数据的恢复工作.
3.2、如何开启AOF方式持久化Redis数据
Redis默认情况下是不开启AOF持久化方式的,如果要开启AOF持久化方式需要在Redis配置文件中进行配置,将下面配置修改为yes(默认是no).
appendonly yes
3.3、同时开启RDB和AOF,那么Redis重新启动恢复数据的时候到底会采用哪种方式恢复数据呢.
Redis默认情况下使不开启AOF持久化方式的,如果RDB和AOF同时开启的情况下,Redis恢复数据会优先采用AOF的方式恢复数据,这样丢失的数据会更少.
3.4、AOF重写原理和机制
1、为什么会重写
AOF采用文件追加的方式,随着时间的推移,.aof文件会越来越大,为了避免这种情况,AOF方式增加了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集,可以使用命令bgrewriteof来手动重写.
2、重写原理
AOF文件持续增长而过大时,会fork出一条新的进程来将文件重写(也是先写临时文件,然后再rename),遍历新进程内存中的数据,然后根据内存中的数据而创建出可以恢复数据的最小指令集,重写AOF文件操作的时候,并没有读取旧的AOF文件,而是将真个内存中的数据库内容用命令的方式重写了一个新的AOF文件.
3、如何触发重写
重写虽然可以节约大量的磁盘空间,恢复数据时也可以减少时间,但是每次重写还是有负担的,需要满足下列条件才能触发重写机制
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
系统载入时或者上次重写完毕时,Redis会记录此时AOF文件的大小,假设为base_size,
如果当前RedisAOF文件
大小>=base_size*(100+100)%
大小>64mb
同时满足这两个条件时便会触发重写机制
4、AOF常用配置详解
################################# APPEND ONLY MODE #################################
#Redis 默认不开启AOF.它的出现是为了弥补RDB的不足(未触发RDB持久化策略,然后宕机的情况下,最后一次未持久化的数据可能会丢失可能会丢失).
所以它采用日志的形式来记录每个写操作,并追加到文件中.Redis重启的会根据日志文件的内容将写指令从前到后执行一次
以完成数据的恢复工作,默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了.但是redis如果中途宕机,
会导致可能有几分钟的数据丢失,根据save策略来进行持久化.
Append Only File是另一种持久化方式,可以提供更好的持久化特性.Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件
每次启动时Redis都会先把这个文件的数据读入内存中,如果开启rdb则使用appendonly no,如果开启aof则使用 appendonly yes
appendonly no
#指定aof模式下本地数据库文件名,默认值为 appendonly.aof
appendfilename "appendonly.aof"
#aof持久化策略的配置:
no表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快
everysec表示每秒执行一次fsync,可能会导致丢失这1s数据
always表示每次写入都执行fsync,以保证数据同步到磁盘,速度最慢
默认使用 everysec
appendfsync always
appendfsync everysec
appendfsync no
# 在aof重写或者写入rdb文件的时候,会执行大量IO,此时对于everysec和always的aof模式来说,执行
fsync会造成阻塞过长时间,no-appendfsync-on-rewrite字段设置为默认设置为no.如果对延迟要求很高的
应用,这个字段可以设置为yes,否则还是设置为no,这样对持久化特性来说这是更安全的选择.设置为yes表
示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no,建议yes.Linux的
默认fsync策略是30秒。可能丢失30秒数据
no-appendfsync-on-rewrite no
#aof自动重写配置.当目前aof文件大小超过上一次重写的aof文件大小的百分之多少进行重写,
即当aof文件增长到一定大小的时候Redis能够调用bgrewriteaof对日志文件进行重写.
当前AOF文件大小是上次日志重写得到AOF文件大小的二倍(设置为100)时,自动启动新的日志重写过.
auto-aof-rewrite-percentage 100
#设置允许重写的最小aof文件大小,避免了达到约定百分比但.aof文件尺寸仍然很小的情况还要重写
auto-aof-rewrite-min-size 64mb
#aof文件可能在尾部是不完整的,当redis启动的时候,aof文件的数据被载入内存.
重启可能发生在redis所在的主机操作系统宕机后,尤其在ext4文件系统没有加上data=ordered选项
(redis宕机或者异常终止不会造成尾部不完整现象.)出现这种现象,可以选择让redis退出,
或者导入尽可能多的数据.如果选择的是yes,当截断的aof文件被导入的时候,
会自动发布一个log给客户端然后load.如果是no,用户必须手动redis-check-aof修复AOF文件才可以
aof-load-truncated yes
#加载redis时,可以识别AOF文件以“redis”开头.字符串并加载带前缀的RDB文件,然后继续加载AOF尾巴
aof-use-rdb-preamble yes
4、RDB和AOF的区别以及选择
RDB | AOF | |
区别 | RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储. | AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录. |
优点 | 这种文件非常适合用于进行备份: 比如说,你可以在最近的 24 小时内,每小时备份一次 RDB 文件,并且在每个月的每一天,也备份一个 RDB 文件。 这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。RDB 非常适用于灾难恢复(disaster recovery)。 | 使用 AOF 持久化会让 Redis 变得非常耐久(much more durable):你可以设置不同的 fsync 策略,比如无 fsync ,每秒钟一次 fsync ,或者每次执行写入命令时 fsync 。 AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,所以主线程可以继续努力地处理命令请求)。 |
缺点 | 如果你需要尽量避免在服务器故障时丢失数据,那么 RDB 不适合你。 虽然 Redis 允许你设置不同的保存点(save point)来控制保存 RDB 文件的频率, 但是, 因为RDB 文件需要保存整个数据集的状态, 所以它并不是一个轻松的操作。 因此你可能会至少 5 分钟才保存一次 RDB 文件。 在这种情况下, 一旦发生故障停机, 你就可能会丢失好几分钟的数据。 | 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。 |
选择 |
如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失, 那么你可以选择使用 RDB 持久化. |
如果你非常关心你的数据的完整性,并且可以接受处理巨大的写入而导致Redis 的性能降低的负面影响,那么你可以选择使用AOF持久化. |