redis-- redis的持久化(作为数据库)

Posted 紫月冰凌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis-- redis的持久化(作为数据库)相关的知识,希望对你有一定的参考价值。

redis是一个基于内存的数据库,故在redis正在运行的数据都在内存中,而内存掉电,内存上所以数据都会消失。故把redis当成数据库使用时就需要对redis进行持久化。

在说redis持久化的时候,我们先来聊聊其他的知识。linux的父子进程。在Linux中使用fork()函数会给当前正在运行的进程创建一个子进程。那么现在问题就来了,fork时父子进程中的数据有什么关系呢?一般说到进程我们都会知道进程间彼此是数据隔离的。然而实际上,子进程在刚创建时,可以看到子进程中的数据。而在修改该数据时,却不会对父进程造成影响。同样子进程也不会受到父进程修改数据的影响。而造成这种现象的,正是因为linux的copy on write机制。

copy on write:是一种内核机制,通俗来讲就是写时复制。及创建子进程并不发生复制,创建子进程后父子进程共用数据。只有在修改数据是才会创建新的空间。

这样做的好处是创建进程变快了。而且根据开发经验,我们创建子进程后不可能父子进程把所有数据都改一遍。而这套机制就是指针支撑的。玩的是指针

redis中有两种数据到存储方式,rdb和aof。下面我们来着重讲一下这两种持久化方式:

1.RDB

rdb持久化的方式

RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储.

redis的rdb持久化方式有存储的是时点数据即某一个时间点的数据。因为如果存储实时更新的数据的话,如果一直有数据写入会导致,持久化过程一直进行,降低了redis的快捷的特性。因此redis有两种持久化数据的方式

  • save:前台更新数据,如果使用这种方法持久化,那么只能在服务器停机维护时,发生因为它会阻塞redis进程造成redis的服务不可用。
  • bgsave:后台运行,该命令的原理是,创建一个子进程来进行redis的持久化,而redis依然提供服务。此时就用到了刚才讲到的copy on write机制,父子进程共用了一套数据。

以上两个命令直接可以在redis的客户端运行。

注意如果使用配置文件的方式配置数据持久化,配置文件中给出bgsave的规则: save这个标识。配置的规则:(要修改的文件是dbfilename dump.rdb,文件一般存储在var/lib/redis/6379)

save 900 1
save 300 10
save 60 10000

该规则意味着,在每60秒检测一次redis的数据量,如果达到10000就进行持久化,否则不持久化。在每300秒检测一次redis的数据量,如果达到10就进行持久化,否则不持久化。在每900秒检测一次redis的数据量,如果达到1就进行持久化,否则不持久化。

rdb方式的优点:

  • RDB是一个非常紧凑的文件,它保存了某个时间点得数据集,非常适用于数据集的备份,比如你可以在每个小时报保存一下过去24小时内的数据,同时每天保存过去30天的数据,这样即使出了问题你也可以根据需求恢复到不同版本的数据集.
  • RDB是一个紧凑的单一文件,很方便传送到另一个远端数据中心或者亚马逊的S3(可能加密),非常适用于灾难恢复.
  • RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能.
  • 与AOF相比,在恢复大的数据集的时候,RDB方式会更快一些.

    rdb的缺点

  • 如果你希望在redis意外停止工作(例如电源中断)的情况下丢失的数据最少的话,那么RDB不适合你.虽然你可以配置不同的save时间点(例如每隔5分钟并且对数据集有100个写的操作),是Redis要完整的保存整个数据集是一个比较繁重的工作,你通常会每隔5分钟或者更久做一次完整的保存,万一在Redis意外宕机,你可能会丢失几分钟的数据.
  • RDB 需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级内不能响应客户端的请求.如果数据集巨大并且CPU性能不是很好的情况下,这种情况会持续1秒,AOF也需要fork,但是你可以调节重写日志文件的频率来提高数据集的耐久度.
  • 不支持拉链化,只有一个rdb文件
  • 丢失数据相对多一些时点与时点之间窗口数据容易丢失。8点得到一个rdb,9点刚要写一个rdb,挂机了。那么8~9之间的数据就会丢失。

    2.AOF

    AOF实际是把对redis操作的操作记录,通过日志的方式记录下来,这样想要恢复数据库文件,只需要把所以指令执行一遍就行。

需要开启aof只需要把dump修改appendonly该为yes即可。

appendonly yes

aof的优点

  • 使用AOF 会让你的Redis更加耐久: 你可以使用不同的fsync策略:无fsync,每秒fsync,每次写的时候fsync.使用默认的每秒fsync策略,Redis的性能依然很好(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失1秒的数据.
  • AOF文件是一个只进行追加的日志文件,所以不需要写入seek,即使由于某些原因(磁盘空间已满,写的过程中宕机等等)未执行完整的写入命令,你也也可使用redis-check-aof工具修复这些问题.
  • Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
  • AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态

    aof的缺点

    弊端,体量无线变大, 恢复慢

为解决aof的弊端日志,优点如果能保住,还是可以用的。就有一个方案:设计一个方案让日志,AOF足够小

就是hdfs,fsimage+edits.log 。让日志只记录增量,合并操作的中间过程。

而4.0版本也是这项技术的分界点

  • 4.0以前进行重写时,删除抵消的命令合并重复的命令。这样最终也是一个纯指令的日志文件
  • 4.0以后将老的数据RDB到aof文件中,将增量的以指令的方式Append到AOFAOF是一个混合体。其利用了RDB的快,利用了日志的全量

从这点可以看出,aof和rdb是可以共存的。

3.持久化的其他特性

日志重写

Redis 支持一种有趣的特性: 可以在不打断服务客户端的情况下, 对 AOF 文件进行重建(rebuild)。执行 BGREWRITEAOF 命令, Redis 将生成一个新的 AOF 文件, 这个文件包含重建当前数据集所需的最少命令。Redis 2.2 需要自己手动执行 BGREWRITEAOF 命令; Redis 2.4 则可以自动触发 AOF 重写, 具体信息请查看 2.4 的示例配置文件。

工作原理

AOF 重写和 RDB 创建快照一样,都巧妙地利用了写时复制机制:

  • Redis 执行 fork() ,现在同时拥有父进程和子进程。子进程开始将新 AOF 文件的内容写入到临时文件。
  • 对于所有新执行的写入命令,父进程一边将它们累积到一个内存缓存中,一边将这些改动追加到现有 AOF 文件的末尾,这样样即使在重写的中途发生停机,现有的 AOF 文件也还是安全的。
  • 当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号之后,将内存缓存中的所有数据追加到新 AOF 文件的末尾。

搞定!现在 Redis 原子地用新文件替换旧文件,之后所有命令都会直接追加到新 AOF 文件的末尾。

redis的持久化想要开启其实挺简单的只需要,修改conf配置文件的几个配置项即可。

rdb和aof混合使用

当二者混合使用时,如果redis服务器停止后重新运行,那么redis恢复数据只会从aof中同步,而不会去向rdb同步。而且在主从复制时,rdb会记录上一次连接的端口,而aof不会。所以主从复制时,如果没有开启aof,那么从服务器在断开主服务器后重新连接主服务器,只会同步从服务器断开时的增量数据,而开启aof后从服务器需要同步主服务器中的所有内容。

以上是关于redis-- redis的持久化(作为数据库)的主要内容,如果未能解决你的问题,请参考以下文章

作为程序员你不知道 Redis 持久化,如何通过面试?

010 redis持久化之RDB

redis学习——数据持久化

redis持久化

redis入门

面试系列16 redis的持久化