一、为什么需要持久化
Redis的强劲性能很大程度上是因为将所有数据存储到内存中,然而当Redis重启之后,这些数据会消失。所以在一些情况下,我们希望redis在重启后数据没有丢失。
- 将redis作为数据库使用。
- 将redis作为缓存服务器,
二、定义
redis将内存中的数据同步到硬盘之中,并且在重启后可以根据硬盘中的内容恢复数据。
三、RDB方式
RBD持久化是通过快照(snapshotting)来实现的,当满足某一条件之后,redis会自动将内存中的所有数据生成一份副本存储到硬盘上,这个过程就是快照。redis进行快照的集中情况:
- 根据配置规则进行快照;
- 用户执行SAVE或者BGSAVE命令;
- 用户执行FLUSHALL命令;
- 发生复制时。
1.根据配置规则自动快照
用户可以再配置文件中自定义快照规则,格式如下:SAVE m n(m:时间,n:数量。每当时间M内被改动的键的数量大于n时触发条件)
save 900 1
save 300 10
save 60 10000
每条快照条件占一行,以SAVE开头,可以同时存在多个快照条件,它们之间是“或”的关系。
2.执行SAVE或BGSAVE命令
- SAVE:当执行SAVE命令,redis同步的进行快照操作,同事阻断所有来自客户端的请求,当数据库中数据较多时会造成服务器较长时间不响应,要尽量避免在生产环境中使用此命令
- BGSAVE:需要手动快照时推荐使用BGSAVE,BGSAVE可以在后台异步的进行快照操作,快照的同时服务器还可以继续响应来自客户端的请求,可以通过LASTSAVE来判断快照是否执行成功。
3.执行FLUSHALL命令
执行FLUSHALL命令会删除数据库中所有数据。所以不论是否触发快照的执行条件,只要配置规则不为空,都会进行快照,如果配置规则为空,则不进行快照。
4.执行复制时
当设置了主从模式时,redis会在复制初始化时进行快照(不论是否设置自动快照条件)。
5.快照原理
redis默认会将快照文件存储在dump.rbd文件中,可以通过配置dir和dbfilename参数分别指定快照文件的存储位置和文件名。快照的过程如下:
(1)Redis使用fork函数复制一份当前进程(主进程)的副本(子进程);
(2)主进程继续接受客户端发来的数据并处理,而子进程则开始将内存中的数据写入硬盘中的临时文件;
(3)当子进程写入完所有的数据后,会用此临时文件替换旧的RDB文件,至此一次快照完成。
redis在进行快照的过程中不会修改RDB文件,只有在快照结束后才会用将旧文件替换。也就是说在任何时候RDB文件都是完整的,这使得我们可以定时备份RDB文件来实现redis数据库备份,redis启动会读取RDB文件,通常将一个记录为1000万条,大小为1G的文件读取到内存中的时间是20~30秒。
通过RDB方式实现持久化,一旦redis异常退出,会丢失上一次快照至今的所有数据,这就需要通过组合设置自动快照条件的方式来将损失降到可以接受的范围之内,如果数据比较重要,则可以采用AOF方式进行持久化。
四、AOF方式
当使用redis存储非临时数据时,一般需要打开AOF持久化降低进程终端造成的数据损失,AOF可以将redis执行的每一条写命令追加到硬盘文件中,这一过程显然会降低redis的性能,使用更快的硬盘可以提高AOF的性能。
1.开启AOF
默认redis是不开启AOF的,可以通过appendonly参数启用:
appendonly yes
AOF文件的保存位置和RDB文件相同,都是通过dir参数设置的,可以通过appendfilename来设置AOF文件名,默认为appendonly.aof
2.AOF实现
AOF以纯文本的形式记录了redis的写命令。
3.同步硬盘数据
由于操作系统的限制,redis每次执行更改数据库内容的操作时,AOF的数据记录并没有真正的写入到AOF文件中,而是进入了系统的硬盘缓存,默认为30秒执行一次同步操作,这就要求redis在写入AOF文件后主动请求系统将缓存内容同步到硬盘中去。在redis中可以通过appendfsync参数来设置同步时机:
#appendfsync always
appendfsync everysec
#appendfsync no
everysec参数表示每秒同步一次。
redis还允许同时启用RDB和AOF两种持久化方式,既保证了数据安全又使得备份等操作十分容易,此时重启redis会采用AOF的方式来恢复数据,因为AOF的持久化方式可能丢失的数据更少。