众所周知,redis是一个内存数据库,既然是将数据保存在内存中,上下线以后数据天然就会丢失,在咱们的业务中,这种状况固然是不容许发生的,因此这时候就须要涉及到redis的持久化机制linux
redis能够手动开启持久化,来让内存中的数据持久化到磁盘上,redis提供了如下两种持久化方案:redis
接下来咱们就要针对这两种方式来作一个讲解数据库
rdb快照的原理是对redis中的数据进行周期性的持久化,也能够理解为redis每隔一段时间就把当前内存数据的状态持久化到磁盘中windows
这个具体的操做并非由工做进程来完成的,redis会调用fork函数来建立一个子进程,父进程会正常执行客户端发来的请求操做,而子进程会把当前的数据库快照写入到临时文件中,最后替换原有的文件(默认为dump.rdb)缓存
因为操做系统的copy-on-write机制,父子进程是共享物理页面的,当父进程处理写请求时,操做系统为父进程要修改的页面建立一个副本,因此子进程地址空间的数据只是当前时刻整个数据库的一个快照,也这就是把这种方式叫作rdb快照的缘由bash
这种方式的优势很明显:服务器
可是其也有缺点:app
redis是默认开启这种持久化方式的,能够打开redis.conf文件,若是是window系统就打开redis.window.conf(redis.windows-service.conf文件是做为系统服务启动时加载的配置文件,若是你设置redis为系统服务,就打开这一个),会发现下面这些配置:函数
save 900 1
save 300 10
save 60 10000
复制代码
咱们拿save 900 1
这条配置来举例,其含义就是在900秒内,若是至少有1个key值发生了变化,就进行内存快照
,咱们查看默认的这些配置也能够发现,这些save语句是能够同时出现的,因此你能够配置不少这样的rdb快照设置性能
看名字应该能猜得出,这种持久化模式是采用日志来进行的,aof模式经过把每条指令追加到日志文件中(默认为appendonly.aof文件),当redis重启后,经过回放aof日志文件中的操做来实现数据集的恢复
开启了aof持久化模式后,redis会将全部收到的修改命令经过write函数追加到日志文件中,具体的执行能够设置如下3种:
这三种模式分别对应配置文件中的appendfsync always
、appendfsync everysec
,和appendfsync no
接着咱们能够看一下aof日志的内容,这里截取了一小段我测试的aof文件:
set
$3
bbb
$3
aaa
*3
$3
set
$3
aaa
$3
ccc
*2
$3
del
$3
aaa
复制代码
能够看出,全部的修改命令都是经过命令符-数据库名-key值
这样的顺序来保存的,可读性也很高
可是aof日志依然有一个问题,若是咱们反复地执行set操做,那么aof日志中就会重复地保存这些没必要要的操做,由于这些命令最终的执行结果和一个set命令的执行结果没有任何区别,那怎么解决这种数据冗余问题呢?
其实这一点redis开发人员也想到了,redis提供了bgrewriteaof命令,收到此命令的redis服务器会自动fork出一个子进程,这个子进程会根据内存中的数据快照,来建立一个用于恢复当期数据的最小日志文件,当写入完成后,子进程会向父进程发送信号,而后父进程把缓存中的修改命令也写入这个临时文件中,并用这个临时文件来替换原aof文件
这份生成的aof文件你会发现几乎都是set操做,并且基本不会出现对一个值重复的set命令,因此恢复起来也至关迅速
aof模式的优势以下:
可是也依然有缺点:
在日常使用时,咱们不能说哪一种就是最好的,而要根据实际状况来选择,这里我提供一些选择的建议:
没错,在使用时能够同时配置rdb和aof两种模式,redis官方也推荐咱们这么作,aof为主,rdb为辅,aof记录日志,rdb作数据库备份,以及aof引擎失效后的替代
持久化的讲解到这里基本就结束了,这里仅仅是带你们简要了解了一下redis持久化的内容,本文一部分是我的的理解、总结与实践,一部分是参考Redis Persistence – Redis这篇官方文档,若有什么错误欢迎指正