Redis 的 2 种持久化方式 Snapshot(RDB) 和 Append-only file(AOF) 的配置和对比
1.Snapshot
1.1 配置参数
save <seconds> <changes>
stop-writes-on-bgsave-error yes
rdbcompression yes
dbfilename dump.rdb
dir ./
- save
:在X秒内如果key有至少X次改变就触发持久化,例如save 900 1的话就是在900秒如果key有至少1次改变就触发持久化。如果想关闭此功能的话,可以把全部save行都注释或删除或者使用save ""。 - stop-writes-on-bgsave-error:在bgsave遇到error的时候是否停止持久化,默认是yes代表是,no代表不是
- rdbcompression:是否压缩,默认是yes代表是,no代表不是,如果想节省CPU的话就设为no,但是rdb文件会比较大
- dbfilename:持久化的文件名字,默认是dump.rdb
- dir:持久化的目录名字,默认是redis.conf所在的目录./
1.2 redis有5种触发snapshot持久化的方式
- 1)客户端执行BGSAVE命令初始化一个会占用一定内存的background进程
- 2)客户端执行SAVE命令,这个时候redis会阻塞所有命令直到snapshot保存完毕,一般很少使用,除非你可以接受redis暂时阻塞或者没有足够内存执行BGSAVE
- 3)redis.conf文件配置了save
,当满足条件的时候自动触发BGSAVE操作 - 4)服务器接收到SHUTDOWN命令或者TERM signal会执行SAVE,redis会阻塞所有命令直到snapshot保存完毕,然后关闭redis
- 5)1台redis连接到另外1台redis并且执行SYNC命令,由于某种原因如果SYNC没有执行,主redis会先执行BGSAVE
需要注意的是如果服务器crash的话会导致自从上次snapshot完成之后的数据丢失
2. Append-only file(AOF)
2.1 配置参数
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
dir ./
- appendonly:是否启动aof,默认是no代表不启用,yes代表启用
- appendfilename:aof的文件名,默认是appendonly.aof
- appendfsync:触发的间隔,默认是everysec代表每秒,另外还有always代表有改变都触发,性能最差但数据最安全,no代表让OS自己决定什么时候执行,性能最好但数据不安全
- dir:和上述是同一个参数(共用),持久化的目录名字,默认是redis.conf所在的目录./
需要注意的是如果你使用了SSD的话,appendfsync设置always会可能导致write amplification从而很大影响SSD的寿命;另外就是aof一般是比rdb文件较大,恢复时间较长,因为要重新执行所有的写操作
3. Rewriting/compacting AOF
3.1 配置参数
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
- no-appendfsync-on-rewrite:在aof rewrite的时候上述appendfsync是否暂时停止,默认是no代表不停止,yes代表停止,不会造成I/O资源竞争,性能较前者好。在日志重写时,不进行命令追加操作,而只是将其放在缓冲区里,避免与命令的追加造成DISK IO上的冲突。
- auto-aof-rewrite-percentage:自动触发aof rewrite的百分比,默认是100%,就是比上次rewrite的1倍
- auto-aof-rewrite-min-size:自动触发aof rewrite的最小size,默认是64mb,就是如果size超过64mb,而且是上次执行的1倍,就会自动触发
因为AOF会以追加的方式记录所有写操作的命令到磁盘文件里面,所以文件会越来越大,导致redis重启的时候恢复时间较长。为了缓解这种问题,redis使用了BGREWRITEAOF,用于删除重复多余的写命令,类似BGSAVE,是一个占用一定系统资源的background进程。因为rewrite的时候会删除旧的AOF文件,如果AOF文件比较大的话,会消耗更多的系统资源
4.Snapshot VS AOF
- snapshot在下一次触发前如果服务器crash了,在上次snapshot之后修改的数据会丢失,而AOF是记录所有的写操作,在数据完整性来说,AOF比snapshot要好
- snapshot持久化的文件rdb一般比aof要小,所以在恢复的时候snapshot会快一点,而且节省硬件资源
- 如果服务器在写aof的时候故障导致aof文件损坏,可以使用自带的工具
redis-check-aof --fix
修复,而snapshot文件rdb损坏是无法修复的所以如果你可以容忍数据丢失的话,可以使用snapshot方式,而且也是比AOF要节省资源,否则的话就使用AOF方式,或者同时使用2种方式(重启的时候会优先使用AOF)。
5.网友翻译的AOF配置部分
原文
############################## APPEND ONLY MODE ###############################
# By default Redis asynchronously dumps the dataset on disk. This mode is
# good enough in many applications, but an issue with the Redis process or
# a power outage may result into a few minutes of writes lost (depending on
# the configured save points).
#
# The Append Only File is an alternative persistence mode that provides
# much better durability. For instance using the default data fsync policy
# (see later in the config file) Redis can lose just one second of writes in a
# dramatic event like a server power outage, or a single write if something
# wrong with the Redis process itself happens, but the operating system is
# still running correctly.
#
# AOF and RDB persistence can be enabled at the same time without problems.
# If the AOF is enabled on startup Redis will load the AOF, that is the file
# with the better durability guarantees.
#
# Please check http://redis.io/topics/persistence for more information.
appendonly no
# The name of the append only file (default: "appendonly.aof")
# appendfilename appendonly.aof
# The fsync() call tells the Operating System to actually write data on disk
# instead to wait for more data in the output buffer. Some OS will really flush
# data on disk, some other OS will just try to do it ASAP.
#
# Redis supports three different modes:
#
# no: don't fsync, just let the OS flush the data when it wants. Faster.
# always: fsync after every write to the append only log . Slow, Safest.
# everysec: fsync only one time every second. Compromise.
#
# The default is "everysec", as that's usually the right compromise between
# speed and data safety. It's up to you to understand if you can relax this to
# "no" that will let the operating system flush the output buffer when
# it wants, for better performances (but if you can live with the idea of
# some data loss consider the default persistence mode that's snapshotting),
# or on the contrary, use "always" that's very slow but a bit safer than
# everysec.
#
# More details please check the following article:
# http://antirez.com/post/redis-persistence-demystified.html
#
# If unsure, use "everysec".
# appendfsync always
appendfsync always
# appendfsync no
# When the AOF fsync policy is set to always or everysec, and a background
# saving process (a background save or AOF log background rewriting) is
# performing a lot of I/O against the disk, in some Linux configurations
# Redis may block too long on the fsync() call. Note that there is no fix for
# this currently, as even performing fsync in a different thread will block
# our synchronous write(2) call.
#
# In order to mitigate this problem it's possible to use the following option
# that will prevent fsync() from being called in the main process while a
# BGSAVE or BGREWRITEAOF is in progress.
#
# This means that while another child is saving, the durability of Redis is
# the same as "appendfsync none". In practical terms, this means that it is
# possible to lose up to 30 seconds of log in the worst scenario (with the
# default Linux settings).
#
# If you have latency problems turn this to "yes". Otherwise leave it as
# "no" that is the safest pick from the point of view of durability.
no-appendfsync-on-rewrite no
# Automatic rewrite of the append only file.
# Redis is able to automatically rewrite the log file implicitly calling
# BGREWRITEAOF when the AOF log size grows by the specified percentage.
#
# This is how it works: Redis remembers the size of the AOF file after the
# latest rewrite (if no rewrite has happened since the restart, the size of
# the AOF at startup is used).
#
# This base size is compared to the current size. If the current size is
# bigger than the specified percentage, the rewrite is triggered. Also
# you need to specify a minimal size for the AOF file to be rewritten, this
# is useful to avoid rewriting the AOF file even if the percentage increase
# is reached but it is still pretty small.
#
# Specify a percentage of zero in order to disable the automatic AOF
# rewrite feature.
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
译文
############################## 仅追加方式 ###############################
#默认情况下Redis会异步的将数据导出到磁盘上。这种模式对许多应用程序已经足够了,
#但是如果断电或者redis进程出问题就会导致一段时间内的更新数据丢失(取决与配置项)
#
#这种只增文件是可选的能够提供更好的体验的数据持久化策略。
#举个例子,如果使用默认的配置数据fsync策略,在服务器意外断电的情况下redis只会丢失一秒中内的更新数据,
#或者当redis进程出问题但操作系统运转正常时,redis只会丢失一个数据更新操作。
#
#AOF 和 RDB 持久化方式可以同时启动并且无冲突。
#如果AOF开启,启动redis时会加载aof文件,这些文件能够提供更好的保证。
#请在 http://redis.io/topics/persistence 获取更多数据持久化信息。
appendonly no
# 只增文件的文件名称。(默认是appendonly.aof)
# appendfilename appendonly.aof
#调用fsync()函数会通知操作系统真正将数据写入磁盘,而不是等待缓冲区中有更多数据。
#有些操作系统会将数据输出到磁盘,有些操作系统只是ASAP。
#
#redis支持三种不同的方式:
#
#no:不调用,之等待操作系统来清空缓冲区当操作系统要输出数据时。很快。
# always: 每次更新数据都写入仅增日志文件。慢,但是最安全。
# everysec: 每秒调用一次。折中。
#
#默认是每秒中一次,因为它往往是在速度和数据安全两者之间的折中选择。
#如果你可以接受让操作系统去自动清空缓存,你可以将这项配置降低到'no'(如果你可以接受一段时间的数据丢失,默认的rdb就足够了),
#这完全取决与你。如果你想要一个更好的体验或者从相反的角度,使用'always',这样会很慢,但是比'everysec'安全些。
#
#请在下面的文章中获取更多细节知识:
# http://antirez.com/post/redis-persistence-demystified.html
#
#如果你不是很清楚这三项之间的区别,或者不知道哪种适合你的机器,就是用默认吧。
# appendfsync always
appendfsync always
# appendfsync no
#当AOF策略设置为'always'或者'everysec'的时候,后台的保存进程会进行很多磁盘I/O操作,
#在某些linux结构中redis会在调用sync()方法时阻塞很长时间。记住,现在还没办法解决这个问题,即使在不同进程中进行调用也会block。
#
#使用如下配置可能会缓解这个问题,这样会在存储大数据或者BIGREWRITEAOF的时候不会在主进程中调用fsync()方法。
#
# 这表示,如果另外一个子进程在进行保存操作,redis的表现如同配置为‘appendfsync no’。
#在实际应用中,这表示在最坏的情景下(使用linux默认配置)可能会丢失30秒日志。
#
#如果你有特殊的情况可以配置为'yes'。但是配置为'no'是最为安全的选择。
no-appendfsync-on-rewrite no
#自动重写只增文件。
#redis可以自动盲从的调用‘BGREWRITEAOF’来重写日志文件,如果日志文件增长了指定的百分比。
#
#它是这样工作的:每次rewrite后redis会记录日志文件的大小。(如果重启后没有重写后的大小,就默认用日志文件大小)
#
# 这个基准日志大小和当前日志大小做比较。如果当前大小比指定的百分比,重写机制就会被触发。
#同时,你也要制定一个重写下线,用来避免增长百分比够了,但是日志文件还很小的情况。
#
#指定百分比为0可以注掉自动重写日志文件功能。
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
评论区