【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后从服务器需要同步主服务器中的所有内容。