redis学习程序员我爱编程

初识Redis(三):Redis数据备份、恢复与持久化

2018-01-02  本文已影响108人  Lee_DH
我们都知道,Redis的读写性能俱佳,但由于是内存数据库,如果没有提前备份,Redis数据是掉电即失的。好在Redis提供了两种方式进行持久化:1、RDB持久化 2、AOF持久化

原理

RDB持久化 AOF持久化

RDB持久化实现

Redis数据库
Redis是一个字典结构的存储服务器,一个Redis实例提供了多个用来存储数据的容器, 客户端可以指定将数据存储在哪个容器中(类似于MySQL中的数据库)。
Redis默认支持16个数据库,可以通redis.conf配置文件修改数据库个数,客户端与Redis建立连接之后默认选择0号数据库
备份
修改配置文件
after 900 sec (15 min) if at least 1 key changed
900秒(15分钟)内至少1个key值改变(则进行数据库保存--持久化)
    
after 300 sec (5 min) if at least 10 keys changed
300秒(5分钟)内至少10个key值改变(则进行数据库保存--持久化)
    
after 60 sec if at least 10000 keys changed
60秒(1分钟)内至少10000个key值改变(则进行数据库保存--持久化) 

save 900 1
save 300 10
save 60 10000

备份文件的名称
dbfilename dump.rdb

备份文件存放路径
dir ./bak   
Redis的SAVE命令和BGSAVE命令用于将当前数据库备份
127.0.0.1:6379> save
OK

127.0.0.1:6379> bgsave
Background saving started

SAVEBGSAVE命令的区别在于:SAVE命令是阻塞主进程,save操作完成之后,主进程才开始工作,客户端可以连接;BGSAVE命令是fork一个专门save的子进程,此操作不会影响主进程

注:SAVE只是将当前的数据库备份,备份文件名默认为dump.rdb,可通过配置文件修改备份文件名 dbfilename xxx.rdb(发现一个问题:如果要对多个数据库进行备份,那么最终只能备份最后一个数据库,因为dump.rdb文件会相互覆盖)

恢复

将备份的RDB文件,放在指定目录,重启Redis即可恢复数据
PS:在练习恢复数据时,碰到一个坑:

1.set一些数据

2. 执行save命令

3. del所有的key

4. 重启,发现数据没有恢复过来

原因:还记得上文提到过的Redis自动RDB备份吗?我在执行第三步操作时,改变了1个以上的key的值,并且这个时间正好是Redis自动备份900秒的最后一秒,所以此时Redis又自动备份了一次,dump.rdb覆盖了旧的rdb文件,还原回去,自然是del之后的数据了。(当然我这个不是凭空臆想的哈,是因为我在步骤2执行save时,看了一下dump.rdb文件的大小,98K,在准备重启之前,我又看了一下dump.rdb文件,73K,说明rdb文件肯定产生了覆盖)

AOF持久化实现

备份
备份过程分以下三个阶段:
进行AOF备份

修改配置文件

#此选项为aof功能的开关,默认为“no”,通过“yes”来开启aof功能
appendonly yes  

#指定aof文件名称
appendfilename appendonly.aof

#备份文件存放路径(此参数同样适用于指定RDB备份文件存放路径)
dir ./

AOF有3种方式将操作命令存入AOF文件

1. appendfsync no 不保存

只执行WHRITE操作,SAVE操作会被略过,只有在Redis被关闭AOF功能被关闭系统的写缓存被刷新(如缓存已被写满)这三种情况,SAVE操作会被执行,但是这三种情况都会引起Redis主进程阻塞

2. appendfsync everysec 每秒钟保存一次

这种模式中,SAVE原则上每隔一秒钟就会执行一次,具体的执行周期和文件写入、保存时,Redis所处的状态有关,此模式下SAVE操作由后台子线程调用,不会引起服务器主进程的阻塞

3. appendfsync always 每执行一个命令保存一次
在这种模式下,每执行一个命令,WRITESAVE都会被执行,且SAVE操作会阻塞主进程

模式 WRITE阻塞 SAVE阻塞 停机时丢失的数据量
appendfsync no 阻塞 阻塞 操作系统最后一次对 AOF 文件触发 SAVE 操作之后的数据
appendfsync everysec 阻塞 不阻塞 一般情况下不超过 2 秒钟的数据
appendfsync always 阻塞 阻塞 最多只丢失一个命令的数据

设置好AOF写入的模式之后,只要达到写入条件(比如一秒钟、执行一个命令),就会自动在指定路径下生成AOF文件,并往里面记录操作命令

AOF文件重写

AOF文件通过同步Redis服务器所执行的命令,实现对数据库状态的记录。有些被频繁操作的键,对它们所调用的命令可能有成百上千、甚至上万条,这样很容易出现AOF文件体积急速膨胀,对Redis甚至整个系统造成影响。

如果服务器对键list执行以下四条命令:

RPUSH list 1 2 3 4      // [1, 2, 3, 4]

RPOP list               // [1, 2, 3]

LPOP list               // [2, 3]

LPUSH list 1            // [1, 2, 3]

那么当前列表键list在数据库的值就是[1,2,3],如果我们要保存这个列表的当前状态,并且尽可能地减少使用命令数,最简单的方法是直接读取list键在数据库的当前值,然后用一条RPUSH list 1 2 3命令代替前面四条命令。

根据键的类型,使用适当的写入命令来重现键的当前值,这就是AOF重写的实现原理

子程序处理: AOF重写程序,会阻塞主进程,作为一种辅助性的维护手段,Redis不希望AOF重写造成服务器无法处理请求,所以Redis会将重写程序放到子进程执行。

AOF重写缓存: 不过,使用子进程也有一个问题需要解决:子进程在进行AOF重写期间,主进程还在继续处理命令,新的数据更新不能同步到重写后的AOF文件中。为了解决这个问题,Redis增加了一个AOF重写缓存,这个缓存在fork出子进程之后开始启用,重写期间的写操作,除了会将写命令追加到现有的AOF文件之外,还会追加到这个缓存中。子进程完成重写操作之后,它会向父进程发送一个完成信号,父进程接到完成信号之后,会调用一个信号函数,将AOF重写缓存中的内容写入新的AOF文件中。

性能影响: 在整个AOF后台重写的过程中,只有最后的写入缓存会造成主进程的阻塞,其他时候,AOF后台重写都不会阻塞主进程。

1. 系统自动后台重写(需满足一定触发条件):

i 没有正在执行的BGSAVEBGREWRITEAOF命令

ii 当前AOF文件大小大于aof_rewrite_min_size

iii AOF文件大小和最后一次重写大小的比率大于aof_rewrite_perc

2. 手动后台重写:

通过BGREWRITEAOF手动重写

恢复

和RDB恢复是一样的操作,将备份的AOF文件,放在指定目录,重启Redis即可恢复数据(具体可参照上文的RDB恢复数据)
ps: 当指定目录同时有RDB文件和AOF文件时,还原数据时AOF文件的优先级是高于RDB文件的,所以优先通过AOF文件还原数据

二者优缺点

RDB持久化
优点:
缺点:
AOF持久化
优点:
缺点:
总结
RDB持久化,性能更好(所有操作均由子进程处理,主进程不进行任何IO操作),数据一致性一般。AOF持久化,数据一致性更好,性能一般(记录操作日志,写入日志和执行日志恢复数据的时间都比RDB更长)。

如果这篇文章对你有帮助,请点个赞哈,感谢

上一篇 下一篇

猜你喜欢

热点阅读