Redis 的数据持久化

摘要:redis 的数据持久化,支持快照 rdb 和日志 aof 两种方式持久化机制,rdb 和 aof 持久化的区别,优点,缺点,持久化的原理等。

RDB 持久化

1、rdb 持久化全称 rdb database。

2、在指定的时间间隔内将内存中的数据集快照写入磁盘。

3、行话称为 snapshot 快照,它恢复时是将快照文件直接读取到内存里。

工作原理

redis 会直接创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,在持久化的过程都结束了,再用这个临时文件替换上次持久化的文件。

fork 的作用是复制一个与当前进程一摸一样的进程,新进程的所有数据,数值都和原进程一致,但是它是一个全新的进程,并且作为原进程的子进程。

整个过程中,主进程是不进行IO操作的,这就确保了极高的性能。如果需要进行大规模的数据恢复,且对数据恢复的完整性不是非常敏感,那 rdb 方式要比 aof 方式更加的高效,rdb 的缺点是最后一次持久化的数据可能会丢失。

保存文件

rdb 默认保存的是 dump.rdb 文件,可以在配置配置文件中修改保存路径和名称。(二进制,没有可读性)

配置文件

#redis.conf

################################ SNAPSHOTTING  ################################

save "" #关闭 rdb 持久化

save 900 1 #15分钟改写了1次,发起快照保存
save 300 10 #5分钟改写了10次,发起快照保存
save 60 10000 #1分钟改写了1万次,发起快照保存

stop-writes-on-bgsave-error yes #如果后台在 save 的时候出错,前台要 stop 写操作

rdbcompression yes #是否启动 LZF 压缩算法

rdbchecksum yes #存储快照以后,redis 会使用 CRC64 算法来进行数据校验

dbfilename dump.rdb #默认的保存文件名

dir ./ #默认保存路径

如何触发快照

1、配置文件中的触发默认快照配置。

2、save 命令,触发 save 命令时,只管保存,不管其它的客户端操作,全部阻塞,等 save 完成后,主进程才开始工作。

[root@host redis]# bin/redis-cli   
127.0.0.1:6379> save
OK

3、bgsave 命令,后台异步快照操作,会 fork 一个 save 的子进程,在执行 save 过程中,不影响客户端的链接,等子进程 fork 执行 save 完成后,通知子进程,子进程关闭。可以通过 lastsave 命令获取最后一次成功执行快照时间。

[root@host redis]# bin/redis-cli 
127.0.0.1:6379> bgsave
Background saving started

4、执行 flushall 命令也会产生 dump.rdb 文件,但是里面是空的,无意义。

从 dump.rdb 恢复数据

将备份文件 dump.rdb 文件移动到 redis 安装目录并且重启服务即可。可以使用命令 config get dir 获取目录。

优势

rdb 是一个非常紧凑的文件,适合大规模的数据恢复,且对数据完整性和一致性要求不高。

劣势

1、在一定时间做一次备份,所以 redis 意外 down 掉的话,就会丢失最后一次快照后的修改。

2、fork 的时候,内存中的数据被克隆了一份,大致 2 倍的膨胀性能需要考虑。


AOF 持久化

1、aof 持久化全称 append only file。

2、以日志形式记录每个写操作,将 redis 执行过得所有写操作指令记录下来(读操作不记录)。

3、只许追加文件但不可以改写文件,redis 启动之初会读取该文件重新构建数据,换言之,redis 重启的话就根据日志文件的内容将写操作指令从前到后执行一次以完成数据的恢复工作。

保存文件

aof 默认保存的是 appendonly.aof 文件。(具有可读性)

配置文件

#redis.conf

############################## APPEND ONLY MODE ###############################

appendonly yes #是否开启 aof 持久化,默认为no

appendfilename "appendonly.aof" #默认的保存文件,可以修改

appendfsync always #同步持久化,每次发生数据变更会立即保存到磁盘,性能较差但是数据安整性比较好
appendfsync everysec #默认设置,异步操作,每秒记录,如果一秒宕机,可能会丢失 1 秒的数据
appendfsync no #不主动调用 fsync 同步,只需要将数据放在操作系统中,更不安全的方法。通常情况下,linux将使用此配置每 30 秒刷新一次数据,但这取决于内核的精确调整

aof 文件修复操作

如果 redis 在运行时宕机,aof 文件在备份时损坏,redis 启动的时候无法从 aof 文件中恢复数据到内存,我们可以使用 redis-check-aof 命令修复。

redis-check-aof --fix appendonly.aof

rewrite(重写机制)

因为 aof 采取文件追加写的方式,所以随着 redis 不断的运行,这个文件会原来越大,数据还原的时间也会越来越长。为了解决这种问题,redis 新增了重写机制,当 aof 文件的大小超过所设定的阈值时,redis 就会启动对 aof 文件内容的压缩(redis 2.4 开始),只保留可以恢复数据的最小指令集(消除冗余命令)。

即使重写执行失败,也不有任何的数据丢失,因为旧的 aof 文件在重写成功之前不会被修改。

#redis.conf

#以下两个配置必须同时满足才会触发重写
auto-aof-rewrite-percentage 100 #当前写入的 aof 文件大小超过上次重写的一倍时触发重写,设置 0 表示不自动重写
auto-aof-rewrite-min-size 64mb #当前 aof 文件大小超过了指定的值才会重写

no-appendfsync-on-rewrite no #重写时是否使用 appendfsync ,用默认既可以了,保证数据安全性

也可以使用命令 bgrewriteaof 手动的触发重写机制。

[root@host redis]# bin/redis-cli 
127.0.0.1:6379> bgrewriteaof
Background append only file rewriting started

rewrite 重写原理和 rdb 的 bgsave 的工作原理类似,redis 会 fork 一个子进程来负责对 aof 文件进行重写。值得注意的是,进行 aof 文件重写时,如果原来的 aof 文件体积已经非常大,那么重写 aof 并删除旧 aof 文件的过程将会对 redis 的性能造成较大的影响。

aof 文件在重写之前具有可读性的,但是重写之后会变成一个二进制文件(不具备可读性)。

优势

利用 appendfsync 持久化机制,异步操作每秒记录,数据完整性要高于 rdb 如果一秒宕机,有可能丢失 1 秒数据。

劣势

1、相同的数据集而言 aof 文件要远大于 rdb 文件。

2、恢复速度要慢于 rdb,aof 运行效率要慢于 rdb。

3、每秒同步策略效率较好,不同步效率和 rdb 相同。


总结

1、如果数据很多,希望快速的恢复和备份,但是对数据的完整度要求不高的话,可以只使用 rdb。

2、rdb 持久化方式能够在指定的时间间隔能对你的数据进行快照存储。

3、aof 持久化方式记录你每次对服务器的写操作,当服务器重启的时候会重新执行这些命令重新构建数据,aof 命令以 redis 协议追加保存每次写的操作到文件末尾。

4、redis 还能对 aof 文件进行后台重写,使得 aof 文件体积不至于过大。

5、如果你只希望你的数据在服务器运行的时候存在,你可以不使用任何持久化方式,相当于一个加强版的 memcache。

6、如果两种持久机制一起打开,当 redis 重新启动时,会优先 aof 重建原始数据集,以为他是保存最完整的。这样也不是就只打开 aof 一种持久化机制,因为 rdb 在数据恢复上比较快,可以做为备用,有备无患。不过可以将 redis.conf 配置中快照机制只保留 save 900 1 这条规则就可以了。

7、rdb 和 aof 的备份文件不要放在本服务器上,如果本服务器物理损坏,数据可能会造成丢失和无法恢复。可以写一个定时任务,每隔多久要把 rdb 或 aof 文件存在到备份的服务器上,以确保数据的安全性。


参考:

Redis Persistence

结束语:感谢您对本网站文章的浏览,欢迎您的分享和转载,但转载请说明文章出处。
Top