目录
一、What's 持久化?
备注:
- 内存:效率高,但断电数据会丢失
- 硬盘:读写速度效率较低(比内存低),断电数据不丢失
备注:
上图来源于《持久化-百度百科》
1.1Redis层面
把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失!!!
二、Redis怎样持久化?
Redis提供了两种方式:
- RDB(默认)
- AOF
三、RDB
这种方式是将内存中的数据以快照的方式写入到二进制文件中,默认生成的文件名为dump.rdb,过程如下:
- 生成临时文件(dump.rdb)
- 写入数据,替代为正式rdb文件
- 删除临时rdb文件
RDB存在三种方式实现:
3.1save命令
备注:
3.2bgsave命令
备注:
3.3服务器配置自动触发
在Redis
配置文件中的指定到达触发RDB持久化的条件,下面来源于redis.conf:
#
# 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 ""
save 900 1
save 300 10
save 60 10000
此方法与bdsave方法类似,只不过他是由服务器自动触发!!!
注意:
由于设定时间太短会导致频繁forks,从而导致频繁写入rdb文件,影响服务器性能;设定时间太长,又会导致数据断电丢失!!!建议:不要在生产环境中使用此方法(自动触发)!!!
3.4优缺点
3.4.1优点
-
快照保存数非常快,还原数据也非常快
-
使用子进程生成,对Redis服务器性能影响较小
-
RDB文件非常适合备份。例如,您可能希望在最近的24小时内每小时存档一次RDB文件,并在30天之内每天保存一次RDB快照。这使您可以在灾难情况下轻松还原数据集的不同版本。
-
RDB对于灾难恢复非常有用,它是一个紧凑的文件,可以传输到远程数据中心。
-
与AOF相比,RDB允许大型数据集更快地重启。
3.4.2缺点
- RDB需要经常使用fork()才能使用子进程将其持久化在磁盘上。如果数据集很大,Fork()可能很耗时,并且如果数据集很大且CPU性能不佳,则可能导致Redis停止为客户端服务几毫秒甚至一秒钟。
- 如果Redis出于任何原因在没有正确关闭的情况下停止工作,数据还是会丢失的。所以假如需要大程度的减少数据丢失,选不要选择RDB!!!
四、AOF
备注:
事实上:通过一个flushAppendOnly函数来实现上述过程!!!
4.1flushAppendOnly功能
- write:将缓冲区写入aof文件
- save:异步(fsync或fdatasync函数),将aof文件保存到磁盘
4.2fsync策略
下面来源于redis.conf:
# 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
#
三种策略(默认:每秒fsync一次):
- 完全没有fsync
- 每秒fsync(每秒的写入性能仍然很好,断电时候只能损失一秒钟的写入时间)
- 每个查询fsync
fsync是使用后台线程执行的,并且在没有进行fsync的情况下,主线程将尽力执行写入操作。
4.3AOF文件重写策略
aof文件大小决定了,加载aof文件恢复数据的快慢,所以aof文件必须尽可能的小!!!Redis支持aof文件重写,通过重写aof,可以生成一个恢复当前数据的最少命令集 ,例如:incr 命令(多条incr命令,重写成一条incr命令)。
4.3.1自动重写
配置文件中修改no-appendfsync-on-rewrite(默认关闭)的值为yes:
# 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
4.3.2手动重写
通过bgrewriteaof命令可以实现手动重写!!!
备注:
4.4AOF文件修复策略
在写入aof日志文件时,如果Redis服务器宕机,则aof日志文件文件会出格式错误,在重启Redis服务器时,Redis服务器会拒绝载入这个aof文件,可以通过以下步骤修复aof并恢复数据。
- 1、备份现在aof文件,以防万一。
- 2、使用redis-check-aof命令修复aof文件,该命令格式如下:
# 修复aof日志文件
$ redis-check-aof -fix file.aof
- 3、重启Redis服务器,加载已经修复的aof文件,恢复数据。
4.5优缺点
4.5.1优点
- AOF日志是仅追加的日志,因此,如果断电,则不会出现寻道或损坏问题。即使由于某种原因(磁盘已满或其他原因)以半写命令结束日志,redis-check-aof工具也可以轻松修复它。
- Redis太大时,Redis可以在后台自动重写AOF。重写是完全安全的,因为Redis继续追加到旧文件时,会生成一个全新的文件,其中包含创建当前数据集所需的最少操作集,一旦准备好第二个文件,Redis会切换这两个文件并开始追加到新的那一个。
4.5.2缺点
- 对于同一数据集,AOF文件通常大于等效的RDB文件。
- 根据确切的fsync策略,AOF可能比RDB慢。通常,在将fsync设置为每秒的情况下,性能仍然很高,并且在禁用fsync的情况下,即使在高负载下,它也应与RDB一样快。即使在巨大的写负载的情况下,RDB仍然能够提供有关最大延迟的更多保证。
参考文献: