当前位置: > 数据库 > Redis >

Redis的两种持久化方式及使用场景分析

时间:2019-05-21 13:54来源:linux.it.net.cn 作者:IT
Redis提供的持久化机制,以及好处:
Redis提供 RDB 和 AOF 两种持久化机制 , 有了持久化机制我们基本上就可以避免进程异常退出时所造成的数据丢失的问题了,Redis能在下一次重启的时候利用之间产生的持久化文件实现数据恢复。
 
一、持久化机制之RDB
我们所谓的RDB持久化就是指的讲当前进程的数据生成快照存入到磁盘中,触发RDB机制又分为手动触发与自动触发
 
1.手动触发RDB
"save"命令,但是"save"命令将会阻塞我们的Redis服务器直到RDB完成,所以真实的环境中一般不会使用该命令。 
 
"bgsave"命令,使用该命令Redis会fork一个子进程来负责RDB持久化,完成持久化后自动结束子进程,所以阻塞只发生在fork的阶段。
 
2自动触发RDB
自动触发RDB只要在redis的conf 配置文件中配置 save相关的配置即可,如 "save m n",这就代表在m秒内我们的数据发生了n次修改就会使用“bgsave”命令自动触发RDB,如不需要即用#将下图的 save 900 1; save 300 10; save 60 10000 注释即可
 
################################ 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 ""
save 900 1   #900秒内发生了1此修改
save 300 10  #300秒内发生了10此修改
save 60 10000 #60秒内发生了10000此修改
RDB注意事项
1、若手动触发RDB一般使用"bgsave"命令,自动触发默认使用的就是"bgsave"命令
 
2、执行"bgsave"命令,Redis会判断是否存在正在执行 RDB的子进程,如果存在了则直接返回
 
3、父进程fork完之后,"bgsave"命令将会返回"Backgroud saving started" 之后就不再阻塞父进程了。
 
4、Redis将RDB文件保存在dir配置的指定的目录下,并且文件名为配置的dbfilename,也可以通过执行config set dir {dirpath}与config set dbfilename {新的文件名字}
 
 
# Since version 5 of RDB a CRC64 checksum is placed at the end of the file.
# This makes the format more resistant to corruption but there is a performance
# hit to pay (around 10%) when saving and loading RDB files, so you can disable it
# for maximum performances.
#
# RDB files created with checksum disabled have a checksum of zero that will
# tell the loading code to skip the check.
rdbchecksum yes
 
# The filename where to dump the DB
dbfilename dump.rdb
# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir /redis_persist/
二、持久化机制之AOF
AOF持久化是以独立的日志记录每次写命令,重启Redis的时候再重新执行AOF文件中命令以达到恢复数据,所以AOF主要就是解决持久化的实时性。
 
1、AOF原理
1)、所有的写入的命令都会被追加到aof_buf这么一个缓冲区中
 
2)、接着AOF缓冲区根据对应的同步策略向磁盘做同步的操作,这里说一下同步策略,同步策略可以通过修改redis配置文件中的参数"appendfsync"进行配置。
 
3)、随着AOF文件变大,定期对文件进行重写操作来压缩文件
 
4)、Redis服务器重启的时候就会加载AOF文件用来恢复数据
 
1)、也就是说如果开启了AOF持久化,我们使用redis输入 "set testkey testValue",在AOF的缓冲区就会追加这么一条文本*3\r\n$3\r\nset\r\n$7\r\ntestkey\r\n$9\r\ntestValue\r\n
 
127.0.0.1:6379> set testkey testValue
OK
 
--AOF文件在缓冲区追加*3\r\n$3\r\nset\r\n$7\r\ntestkey\r\n$9\r\ntestValue\r\n
这里解释一下Redis使用的协议要求每行使用\r\n分隔
这里第一行代表参数数量 $3代表有三个参数  set testkey testValue
参数的字节数分别为 3 7 9
所以翻译出来就是
*3
$3
SET
$7
testkey
$9
testValue
 2)、接着AOF对缓冲区进行同步操作会按照我们配置的如下策略向磁盘进行同步
 
redis配置文件参数appendfsync说明
可配置的值 配置说明
always 命令写入缓冲区就调用fsync操作同步到AOF文件中
everysec 命令写入缓冲区后调用系统write操作,fsync同步文件操作由专门的线程每秒调用一次
no 命令写入缓冲区后调用系统write操作,不对AOF文件做fsync同步,同步操作由系统负责,最迟30秒同步
# 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 everysec
# appendfsync no
若我们配置的为always,则每次写入缓冲区都会同步AOF文件,这样会严重影响redis性能,因为普通磁盘Redis支支持击败TPS写入
 
若配置为No,那每次同步AOF文件的周期不可控,,这样如果还没有进行同步,服务就挂了那数据的安全性没法保证了
 
配置为everysec是最佳的同步策略也是redis默认的同步策略,每秒同步一次,也就是说就算系统宕机了最多丢失1秒的数据并且性能方面也没有太大影响
 
3)、接着redisr对AOF文件进行定期的重写操作来压缩文件,重写操作也就是只保留写入命令忽略del key hdel key srem key 等,并且将多个命令如 lpush list a lpush list b 合并到一起
 
4)、在重启redis再加载持久化文件达到恢复数据的目的,这里有个问题就是AOF和RDB都可以用来持久化,那Redis加载持久化文件的顺序是怎样的,Redis默认是加载AOF文件,如果没有AOF才去加载RDB。
 
 
三、RDB与AOF优劣势分析
1.RDB优劣势
优势:
 
RDB只代表某个时间点上的数据快照,所以适用于备份与全量复制,如一天进行备份一次。
Redis再加载RDB文件恢复数据远快于AOF文件
性能上考虑RDB优于AOF,因为我们保存RDB文件只需fork一次子进程进行保存操作,父进程没有对磁盘I/O
劣势:
 
RDB没办法做到实时的持久化数据,因为fork是重量级别的操作,频繁执行成本过高
RDB需要经常fork子进程来保存数据集到磁盘,当数据集比较大额时候,fork的过程是比较耗时的,可能会导致redis在一些毫秒级不能响应客服端请求
老版本的Redis无法兼容新版本的RDB文件

 
2.AOF优劣势
优势:
 
通过配置同步策略基本能够达到实时持久化数据,如配置为everysec,则每秒同步一次AOF文件,也就是说最多丢失一秒钟的数据,兼顾了性能与数据的安全性
AOF 文件是一个只进行追加操作的日志文件(append only log), 因此对 AOF 文件的写入不需要进行 seek , 即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等等), redis-check-aof 工具也可以轻易地修复这种问题。
劣势:
 
对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
与AOF相比,在恢复大的数据时候,RDB方式更快一些
 
 
(责任编辑:IT)
------分隔线----------------------------