重修Redis之四:搞定RDB和AOF持久化机制

     Redis是内存服务器,而且数据时以键值对的形式存储。对于内存服务器来说,如果是数据库数据没有定时备份,一旦服务器出现故障或者停机,那么数据将会消失不见,这将是灾难级别的影响。为了解决这个问题,Redis提供了持久化机制RDB和AOF。

RDB持久化

基本操作流程

      RDB持久化是将内存中的数据以快照的形式保持在磁盘中,产生的是一个经过压缩的二进制文件文件(dump.rdp),这样一来如果服务器进程意外停止,数据就可以恢复到文件保存的节点。

 实现方式:

       RDB文件生成主要包SAVE和BGSAVE两个命令来实现。而这个两个方式的主要区别是,SAVE会阻塞Redis服务的进程,直到RDB文件创建完成为止,也就是说SAVE期间无法接受其他请求;而BGSAVE是在保证主进程的同时,会fork一个子进程来实现RDB文件,不会影响主进程的活动,当子进程完成写临时文件后,将原来的 RDB 替换掉,这样的好处是可以 copy-on-write。而RDB文件的载入是在Redis服务启动时只要检测到RDB文件存在就会自动载入。

自动间歇性保存

        SAVE时会阻塞主进程,不是备份数据的首选。而BGSAVE执行时fork子进程,不影响客户端对主进程的请求。所以Resdis可以通过设置save参数来让服务器自动执行BGSAVE备份数据。redis.conf主要配置如下:

################################ SNAPSHOTTING  ################################
#
# Save the DB on disk:
#
#   save <seconds> <changes>
#
#   Will save the DB if both the given number of seconds and the given
#   number of write operations against the DB occurred.
#
#   In the example below the behaviour will be to save:
#   after 900 sec (15 min) if at least 1 key changed
#   after 300 sec (5 min) if at least 10 keys changed
#   after 60 sec if at least 10000 keys changed
#
#   Note: you can disable saving completely by commenting out all "save" lines.
#
#   It is also possible to remove all the previously configured save
#   points by adding a save directive with a single empty string argument
#   like in the following example:
#
#   save ""

save 900 1
save 300 10
save 60 10000

满足以下三个条件:BGSAVE就会被执行:

  • 服务器900秒之内,对数据库进行了至少1次修改;
  • 服务器在300秒内,对数据库进行至少10次修改;
  • 服务在60秒内,对数据库进行了至少1000次修改

         Redis主要通过维护一个dirty计数器来保存对数据库修改的次数(修改次数是根据元素个数判断)和lastsave来记录执行保存的操作时间。在通过周期性的检查(每隔100ms)执行,来确认是否满足条件来执行BGSAVE操作。

RDB文件示例:

REDIS       db_version                   databases     EOF     check_sum
标志     长度4字节版本号 数据库 正文内容   校验数    (8个字节)

 

 

REDIS 0006 :Redis版本号 

\0 003 age 300 023: 0表示字符串类型的key,003表示key的长度,age是key ,300表示长度,023表示value

1 020 4 P G 232 211 350 :表示八字节长的校验和。

AOF持久化

基本操作流程:

AOF持久化与RDF不同的是,AOF是通过保存Redis服务所执行的写命令来记录数据库钻状态的。以纯文本的形式以Redis的命令请求协议格式保存,包括SET、SADD、RPUSH命令。

实现原理:

AOF持久化默认关闭的,需要修改redis.conf配置开启

############################## APPEND ONLY MODE ###############################
appendonly yes

AOF持久化实现分为三个步骤,命令追加,文件写入,文件同步。整个过程是一个一个轮循事件,命令追加是在有写的操作命令时,会以协议格式被追加到个aof_buf缓冲区的末尾。而文件写入和文件步骤是根据redis.conf的中的appendfsync来决定的。

void aof{
 //追加到缓冲区
 apend_aof_buf();
 //处理时间事件
 timeEvents();
 //考虑是否写入同步(appendfsync来决定的)
 flusshFile();
}

 appendfsync的三种模式

############################## APPEND ONLY MODE ###############################
#always 服务器在每个事件循环都要将aof_buf缓冲区中的所有内容写入到AOF文件中,效率最慢,但是最安全,即使出现故障停机,AOF持续化也只会丢失一个事件循环所产生的命令数据
# appendfsync always
# everysec 服务器在每个事件循环都要将aof_buf缓冲区所有内容写入到AOF文件,并且每隔一秒就要在子线程中对AOF进行一次同步。效率比较快
appendfsync everysec
# no 服务器在每个事件循环都要将aof_buf缓冲区所有内容写入到AOF文件,至于何时对AOF进行同步,由操作系统控制,写入速度最快。但是由于积累数据较多,导致同步时间最长,停机时会导致上次同步的AOF文件后的数据丢失
# appendfsync no

加入缓冲区是为提高文件写入的效率,但是同样带来了安全问题,缓冲区的数据毕竟还加载在内存中,如果此时停服务会使得缓存区中的数据丢失。系统服务提供了函数fsync和fdata_sync可以强制将缓冲区的数据立即写入到磁盘中,这也就是AOF持久化是实现同步和写入的原理。

AOF重写:

实现重写的原因:

       AOF文件存储的操作数据的命令,而且随着时间的推移操作的命令会来越来越多,文件体积也会越来越大,占用磁盘空间越大,使用AOF文件数据还原的时间也会越来越长。所有Redis提供了AOF重写功能,通过创建一个新的AOF文件提换原来的AOF文件。新文件中不需要分析、读取就的AOF文件内容,新旧文件保存的数据状态相同,新AOF文件不会包含任何浪费空间的冗余命令。例如:存储一个list分6次存处元素,但是新的AOF文件只会保留RPUSH多个元素的命令,这样就大大节省AOF文件的体积。

执行:

AOF重写是fork出一个子进程来进行执行,将数据方入到AOF的重写缓冲区不影响主进程的处理请求,进程操作在无锁状态下保证了数据的安全性。

 手动执行:

BGREWRITEAOF

自动执行配置:

############################## APPEND ONLY MODE ###############################
#当前的AOF文件大小超过上一次重写时AOF文件大小的百分比会进行重写,如果之前没有重写过,则以启动文件启动大小为依据
auto-aof-rewrite-percentage 100
#允许重写的最小AOF文件大小
auto-aof-rewrite-min-size 64mb

AOF文件示例:

如何选择两种持久化机制?

      RDB非常适合做备份,可以分时间段进行备份,如果允许丢失短时间的数据可以只使用RDB机制,而RDB的缺点也就是因为时效问题,如果因为数据库故障时,那么在上个备份版本之间的数据都会丢失;

      而AOF使得数据丢失已经降到很低,everysec会每秒执行一次fsync 策略,及时数据库故障,也只会丢失1秒的数据,AOF的缺点是文件体积 比RDB要大,速度会比RDB慢,同时执行备份的次数也要比RDB多,备份时会产生大量的IO操作,影响Redis的效率。

     Redis 支持同时开启 RDB 和 AOF,系统重启后,Redis 会优先使用 AOF 来恢复数据,这样丢失的数据会最少。不过Redis4.0以后的版本开始支持 RDB 和 AOF 的混合持久化(默认关闭的,通过配置项 aof-use-rdb-preamble 开启)。如果把混合持久化打开,AOF 重写的时候就直接把 RDB 的内容写到 AOF 文件开头。这样做的好处是可以结合 RDB 和 AOF 的优点, 快速加载同时避免丢失过多的数据。当然缺点就是 AOF 里面的 RDB 部分是压缩格式不再是 AOF 格式,可读性变差。

=================================================================

Redis版本:3.0.7

参考书籍《Redis设计与实现》 黄健宏 著

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值