Redis持久化
简介
Redis是一款单线程、高性能的基于内存的非关系型数据库,常用来做分布式缓存。Redis的数据全部都是存储在内存里,如果服务器突然宕机,数据就会全部丢失。Redis有持久化机制来保证服务器宕机的情况下数据不丢失。
Redis有两种持久化的方式。RDB和AOF。
RDB
持久化就是将数据写入磁盘,以持久化保存的过程。
**在指定的时间间隔内将内存中的数据集快照写入磁盘。**恢复时将快照文件直接读取到内存中。
RDB过程
Redis回单独创建(fork)一个子进程来持久化,会先将内存中的数据写入一个临时文件中,待持久化过程结束了,再用临时文件把上次持久化的文件替换掉。整个过程中,主进程不需要进行任何IO操作,保证了主进程的性能。
RDB默认保存在dump.rdb文件中。
-rw-rw-r-- 1 admin admin 180968 Jul 6 23:19 appendonly.aof
-rw-rw-r-- 1 admin admin 323 Jul 6 23:20 dump.rdb
-rwxrwxr-x 1 admin admin 17072128 Jan 12 04:17 kinsinghRkRXtnt7Z
-rw-r--r-- 1 admin admin 50744 Jan 12 04:17 red2.so
Fork:
fork的作用是复制一个与当前进程一样的进程。新进程为当前进程的子进程。子进程的数据和主进程一样,但是一个全新的进程。子进程读取内存中的数据,然后序列化到磁盘上。
何时触发RDB?
1、 自动触发
redis.conf文件中的配置位置SNAPSHOTTING:
# save ""
save 900 1
save 300 10
save 60 10000
分别表示:“900秒内至少有一个key被改动、300秒内至少有10个key被改动、60秒内至少有10000个key被改动”时,触发一次RDB操作,自动保存数据集。
save “” 表示关闭RDB。
1、 手动触发
save或者是bgsave命令。
- save命令会阻塞,生产环境慎重。
- bgsave是在后台异步进行快照保存,同时还可以响应客户端的请求。
优劣势
1、 优势
- 整个redis中只有这一个备份文件,不用经常进行备份。适合大规模的数据恢复。
- 性能最大化。通过fork子进程来持久化,同时主进程又能继续处理客户端的请求。
- 相较于AOF机制,如果数据集很大,启动时数据恢复效率更高更快。
1、 劣势
- 如果服务器突然宕机,还未来得及持久化的数据将会丢失。如果对数据完整性要求较高,不建议采用这种方式。
- 由于是fork了一个与当前进程一样的进程,包含当前进程的所有数据,所以,内存中的数据增加了一倍,性能会有所影响。
AOF
AOF过程
以日志的形式来记录每个写操作,将Redis执行过的所有写指令都记录下来(读操作不需要记录),将命令追加到日志文件中。
Redis启动时会读取该文件重新构建数据,也就是将文件中保存的命令重新执行一遍,也就是重放。
AOF默认保存在appendonly.aof文件中。
-rw-rw-r-- 1 admin admin 180968 Jul 6 23:19 appendonly.aof
-rw-rw-r-- 1 admin admin 323 Jul 6 23:20 dump.rdb
-rwxrwxr-x 1 admin admin 17072128 Jan 12 04:17 kinsinghRkRXtnt7Z
-rw-r--r-- 1 admin admin 50744 Jan 12 04:17 red2.so
redis.conf文件中的配置位置APPEND ONLY MODE:
appendonly yes
# The name of the append only file (default: "appendonly.aof")
appendfilename "appendonly.aof"
AOF配置项:
# appendfsync always
appendfsync everysec
# appendfsync no
appendfsync表示redis多久将数据fsync到磁盘一次。
默认是appendfsync everysec 也就是每隔一秒就执行一次。这种配置下,即使服务器突然宕机,最多只丢失一秒钟的数据。
appendfsync always表示每当有写命令执行时都进行一次fsync,这样能保证数据完整,但是十分影响性能。
Rewite(AOF重写)
如果采用文件追加方式,那么AOF文件会越来越大,重启恢复时会非常耗时。所以,redis提供了AOF重写机制,当AOF文件超过设定的阈值时,redis将aof文件重写,只保存恢复数据的最小执行集。
rewirte原理:
AOF文件持续增长而过大时,会fork出一个新的进程来重写文件,创建出临时文件,将内存中的数据的set语句命令追加到临时文件中,然后用临时文件替换掉原来的aof文件。
rewirte没有读取原来的AOF文件。
触发机制:
- bgrewiteaof 手动触发
- Redis会记录上次重写时的AOF大小,默认是当AO文件大小是上次rewrite后大小的一倍且文件大于64M时触发。
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
Redis-check-aof –fix
如果AOF文件出错了怎么办?
如果在AOF的过程中服务器宕机,命令没有全部追加到日志中,造成AOF文件出错,那么redis重启时会拒绝载入这个文件。
我们使用Redis-check-aof –fix来修复出错的文件。
优劣势
1、 优势
- 更高的数据安全性和完整性。默认情况下每秒同步,最多丢失一秒的数据。
- Fsync也是后台异步的,效率非常高。
- 提供 Redis-check-aof –fix机制,确保数据正确性。
1、 劣势
- AOF文件相较于RDB文件大得多,数据恢复效率低。
- AOF虽然是后台异步fsync追加日志文件,无论是每秒同步还是每修改同步,都是消耗一部分性能。
总结
- RDB保存某一时刻内存数据集的快照。
- AOF以追加形式保存的命令日志文件。
- 通常AOF文件比RDB文件大,数据恢复效率较低。
- AOF数据安全性、完整性比RDB高,RDB丢失数据风险大。
- 根据fsync策略不同,AOF对redis的性能影响比RDB大。
如果同时开启了两种持久话方式,redis数据恢复时会采用哪一种呢?
如果同时开启两种持久化方式,redis重启时会采用AOF文件来恢复数据。因为AOF文件保存的数据比RDB要完整,RDB丢失数据的风险要大一些。
本文使用 tech.souyunku.com 排版