浅谈Redis的两种持久化机制

前言

众所周知,redis是一个内存数据库,既然是将数据保存在内存中,上下线以后数据天然就会丢失,在咱们的业务中,这种状况固然是不容许发生的,因此这时候就须要涉及到redis的持久化机制linux

redis能够手动开启持久化,来让内存中的数据持久化到磁盘上,redis提供了如下两种持久化方案:redis

  • RDB快照
  • AOF日志

接下来咱们就要针对这两种方式来作一个讲解数据库

RDB快照

rdb快照的原理是对redis中的数据进行周期性的持久化,也能够理解为redis每隔一段时间就把当前内存数据的状态持久化到磁盘中windows

这个具体的操做并非由工做进程来完成的,redis会调用fork函数来建立一个子进程,父进程会正常执行客户端发来的请求操做,而子进程会把当前的数据库快照写入到临时文件中,最后替换原有的文件(默认为dump.rdb)缓存

因为操做系统的copy-on-write机制,父子进程是共享物理页面的,当父进程处理写请求时,操做系统为父进程要修改的页面建立一个副本,因此子进程地址空间的数据只是当前时刻整个数据库的一个快照,也这就是把这种方式叫作rdb快照的缘由bash

这种方式的优势很明显:服务器

  • RDB模式下会不断产生快照文件,均表明某一时刻redis中的数据,能够用做冷备份
  • 采用子进程来执行磁盘IO,写入快照的时候对redis的影响很是小,能够保持redis的高性能
  • 重启和恢复redis数据的速度很快

可是其也有缺点:app

  • 若是在两次快照之间发生宕机,则其间写入的数据会丢失
  • 每次fork的时候,若是数据很大,则会产生必定时间的服务暂停

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日志

看名字应该能猜得出,这种持久化模式是采用日志来进行的,aof模式经过把每条指令追加到日志文件中(默认为appendonly.aof文件),当redis重启后,经过回放aof日志文件中的操做来实现数据集的恢复

开启了aof持久化模式后,redis会将全部收到的修改命令经过write函数追加到日志文件中,具体的执行能够设置如下3种:

  • always:每次有修改操做就强制写入
  • everysec:每秒钟强制写入(推荐使用)
  • no:不主动进行持久化,将数据存放在操做系统中,通常linux每30分钟刷新一次数据

这三种模式分别对应配置文件中的appendfsync alwaysappendfsync 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模式的优势以下:

  • 可读性很是高,若是发生了误操做,能够在rewrite操做以前拷贝一份aof日志文件,将其中的误操做删去,而后替换原有文件便可,不影响redis的恢复读取,能够用来做为紧急恢复
  • 丢失数据的概率很低,即便丢失也不会有太大影响(若是设置了每秒备份,则最多会丢失1s内写入的数据)

可是也依然有缺点:

  • aof文件通常大于rbd文件
  • 根据选择的fsync策略的不一样,aof的速度可能会慢于rdb
  • 在写入负载很大的状况下,aof不能提供最大延迟的保证,而rbd能够
  • 有概率发生不能彻底恢复redis数据的bug

使用场景

在日常使用时,咱们不能说哪一种就是最好的,而要根据实际状况来选择,这里我提供一些选择的建议:

  • 若是你能够容许当发生宕机时有几分钟的数据丢失,那么就使用RDB快照模式,它可让你更快地重启redis
  • 其他状况均推荐采用RDB+AOF的模式

没错,在使用时能够同时配置rdb和aof两种模式,redis官方也推荐咱们这么作,aof为主,rdb为辅,aof记录日志,rdb作数据库备份,以及aof引擎失效后的替代

总结

持久化的讲解到这里基本就结束了,这里仅仅是带你们简要了解了一下redis持久化的内容,本文一部分是我的的理解、总结与实践,一部分是参考Redis Persistence – Redis这篇官方文档,若有什么错误欢迎指正

相关文章
相关标签/搜索