Redis持久化及复制

1、持久化的两种方式

一、RDB:redis

RDB是在指定时间间隔内生成数据集的时间点快照(point-in-time snapshot)持久化,它是记录一段时间内的操做,一段时间内操做超过多少次就持久化。
默认是会以快照的形式将数据持久化到磁盘的(一个二进制文件,dump.rdb,这个文件名字能够指定),在配置文件中的格式是:save N M表示在N秒以内,redis至少发生M次修改则redis抓快照到磁盘。固然也能够手动执行save或者bgsave(异步)作快照。
工做原理:
当redis须要作持久化时,redis会fork一个子进程;子进程将数据写到磁盘上一个临时RDB文件中;当子进程完成写临时文件后,将原来的RDB替换掉,这样的好处就是能够copy-on-write(写时复制技术)数据库

二、AOF:安全

AOF持久化记录服务器执行的全部写操做命令,并在服务器启动时,经过从新执行这些命令来还原数据集,它能够实现每次操做都持久化。
AOF文件中的命令所有以redis协议的格式来保存,新命令会被追加到文件的末尾。 redis还能够在后台对AOF文件进行重写(rewrite),使得AOF文件的体积不会超出保存数据集状态所需的实际大小。redis还能够同时使用AOF持久化和RDB持久化。在这种状况下,当redis重启时,它会优先使用AOF文件来还原数据集, 由于AOF文件保存的数据集一般比RDB文件所保存的数据集更完整。也能够关闭持久化功能,让数据只在服务器运行时存在。服务器

RDB方法在redis异常死掉时,最近的数据会丢失(丢失数据的多少视你save策略的配置),因此这是它最大的缺点,当业务量很大时,丢失的数据是不少的。
Append-only方法能够作到所有数据不丢失,但redis的性能就要差些。AOF就能够作到全程持久化,只须要在配置文件中开启(默认是no),appendonly yes开启AOF以后,redis每执行一个修改数据的命令,都会把它添加到aof文件中,当redis重启时,将会读取AOF文件进行“重放”以恢复到redis关闭前的最后时刻。网络

redis启动装载:
AOF优先于RDB 
RDB性能优于AOF,由于里面没有重复 
Redis一次性将数据加载到内存中,一次性预热架构

LOG Rewriting(重写)随着修改数据的执行AOF文件会愈来愈大,其中不少内容记录某一个key的变化状况。所以redis有了一种比较有意思的特性:在后台重建AOF文件,而不会影响client端操做。在任什么时候候执行bgrewriteaof命令,都会把当前内存中最短序列的命令写到磁盘,这些命令能够彻底构建当前的数据状况,而不会存在多余的变化状况(好比状态变化,计数器变化等),缩小的AOF文件的大小。因此当使用AOF时,redis推荐同时使用bgrewriteaof。AOF 重写和 RDB 建立快照同样,都巧妙地利用了写时复制机制。app

为了压缩AOF的持久化文件,Redis提供了bgrewriteaof命令。
收到此命令后Redis将使用与快照相似的方式将内存中的数据以命令的方式保存到临时文件中,最后替换原来的文件,以此来实现控制AOF文件的增加。
因为是模拟快照的过程,所以在重写AOF文件时并无读取旧的AOF文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的AOF文件。异步

AOF文件刷新的方式,有三种,参考配置参数appendfsync :
    appendfsync always:    每提交一个修改命令都调用fsync刷新到AOF文件,很是很是慢,但也很是安全;
    appendfsync everysec: 每秒钟都调用fsync刷新到AOF文件,很快,但可能会丢失一秒之内的数据;
    appendfsync no:           依靠OS进行刷新,redis不主动刷新AOF,这样最快,但安全性就差。默认并推荐每秒刷新,这样在速度和安全上都作到了兼顾。工具

redis默认的持久化方式是RDB。性能

可能因为系统缘由致使了AOF损坏,redis没法再加载这个出错的AOF文件,能够按照下面步骤来修复:
    一、首先作一个AOF文件的备份,复制到其余地方;
    二、修复原始AOF文件,执行命令redis-check-aof –fix ;
    三、能够经过diff –u命令来查看修复先后文件不一致的地方;
    四、重启redis服务。

LOG Rewrite的工做原理:
一样用到了copy-on-write:首先redis会fork一个子进程;子进程将最新的AOF写入一个临时文件;父进程增量的把内存中的最新执行的修改写入(这时仍写入旧的AOF,rewrite若是失败也是安全的);当子进程完成rewrite临时文件后,父进程会收到一个信号,并把以前内存中增量的修改写入临时文件末尾;这时redis将旧AOF文件重命名,临时文件重命名,开始向新的AOF中写入。

为以防万一(机器坏掉或磁盘坏掉),最好按期把使用filesnapshotting 或 Append-only 生成的*rdb *.aof文件备份到远程机器上,而后能够用crontab定时(好比每半小时)scp一次。若是没有使用redis的主从功能 ,半小时备份一次应该是能够了;而且若是应用数据量不大的话,能够单机部署,作主从有点浪费。具体仍是要根据应用而定。

接着具体解说下这两种持久化:

若是的内存中的数据量很是大的时候,rdb持久化的临时文件就会很是大,几乎是原文件的1倍,性能有所下降。
若是当写操做要马上持久化的时候,能够执行命令:save
save是全阻塞的,bgsave是异步的。
snapshot快照首先将数据写入临时文件,当成功结束后,将临时文件重名为dump.rdb
 
使用RDB恢复数据:
自动的持久化数据存储到dump.rdb后。实际只要重启redis服务便可完成(启动redis的server时会从dump.rdb中先同步数据)
 
客户端使用命令进行持久化save存储:
   redis-cli -h ip -p port save
   redis-cli -h ip -p port bgsave
一个是在前台进行存储,一个是在后台进行存储。个人client就在server这台服务器上,因此不须要连其余机器,直接./redis-cli bgsave。
因为redis是用一个主线程来处理全部 client的请求,这种方式会阻塞全部client请求。因此不推荐使用。另外一点须要注意的是,每次快照持久
化都是将内存数据完整写入到磁盘一次,并非增量的只同步脏数据。若是数据量大的话,并且写操做比较多,必然会引发大量的磁盘io操做,可能会严重影响性能
 
若是aof或rdb文件语法有误,可使用下面两条命令来修复。 1)aof修复命令:
  redis-check-aof --fix appendonlly.aof
2)rdb修复命令:
  redis-check-rdb --fix dump.rdb
 
aof是采用文件追加方式,将全部的写操做保存在aof文件中,当文件愈来愈大时,有可能存在相同的写操做,这些相同的操做能够将他浓缩为一条操做,这样能够减小aof文件的容量。
 
redis对aof新增了一种重写机制,当aof文件大小超过所设定的阈值时,redis会启动aof文件的内容压缩,只保留能够恢复数据的最小指令集,可使用命令bgrewriteaof

RDB和AOF各自的优缺点:
一、RDB持久化优势
RDB 是一个很是紧凑(compact)的文件,它保存了Redis在某个时间点上的数据集。 这种文件很是适合用于进行备份的,好比说,能够在最近的24小时内,每小时备份一次RDB文件,而且在每月的每一天,也备份一个 RDB 文件。这样的话,即便赶上问题,也能够随时将数据集还原到不一样的版本。RDB 很是适用于灾难恢复(disaster recovery):它只有一个文件,而且内容都很是紧凑,能够(在加密后)将它传送到别的数据中心,或者亚马逊 S3 中。RDB能够最大化 Redis 的性能:父进程在保存RDB文件时惟一要作的就是fork出一个子进程,而后这个子进程就会处理接下来的全部保存工做,父进程无须执行任何磁盘 I/O 操做。RDB在恢复大数据集时的速度比AOF的恢复速度要快。

 二、RDB持久化缺点
若是须要尽可能避免在服务器故障时丢失数据,那么RDB不适合这种状况。 虽然Redis容许设置不一样的保存点(save point)来控制保存RDB文件的频率,可是由于RDB文件须要保存整个数据集的状态,因此它并非一个轻松的操做。所以你可能会至少5分钟才保存一次RDB文件。在这种状况下, 一旦发生故障停机,就可能会丢失好几分钟的数据。每次保存RDB的时候,Redis都要 fork() 出一个子进程,并由子进程来进行实际的持久化工做。在数据集比较庞大时, fork() 可能会很是耗时,形成服务器在某某毫秒内中止处理客户端; 若是数据集很是巨大,而且 CPU 时间很是紧张的话,那么这种中止时间甚至可能会长达整整一秒。 虽然 AOF 重写也须要进行 fork() ,但不管 AOF 重写的执行间隔有多长,数据的耐久性都不会有任何损失。

三、AOF持久化优势
使用AOF持久化会让Redis变得很是耐久(much more durable):你能够设置不一样的fsync 策略,好比无fsync ,每秒钟一次 fsync ,或者每次执行写入命令时fsync 。AOF的默认策略为每秒钟fsync 一次,在这种配置下,Redis 仍然能够保持良好的性能,而且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,因此主线程能够继续努力地处理命令请求)。AOF 文件是一个只进行追加操做的日志文件(append only log), 所以对 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文件的体积一般要大于RDB文件的体积。根据所使用的fsync策略,AOF的速度可能会慢于RDB 。在通常状况下,每秒 fsync 的性能依然很是高,而关闭fsync可让AOF的速度和 RDB 同样快, 即便在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 能够提供更有保证的最大延迟时间(latency)。AOF 在过去曾经发生过这样的 bug : 由于个别命令的缘由,致使 AOF 文件在从新载入时,没法将数据集恢复成保存时的原样。 (举个例子,阻塞命令BRPOPLPUSH就曾经引发过这样的 bug 。)测试套件里为这种状况添加了测试:它们会自动生成随机的、复杂的数据集,并经过从新载入这些数据来确保一切正常。 虽然这种 bug 在 AOF 文件中并不常见, 可是对比来讲, RDB 几乎是不可能出现这种 bug 的。

RDB持久化和AOF持久化,应该用哪个?
通常来讲,若是想达到足以媲美PostgreSQL的数据安全性,应该同时使用两种持久化功能。
若是很是关心数据,但仍然能够承受数分钟之内的数据丢失, 那么能够只使用RDB持久化。
不推荐只使用AOF持久化:由于定时生成RDB快照(snapshot)很是便于进行数据库备份,而且RDB恢复数据集的速度也要比 AOF 恢复的速度要快,除此以外,使用RDB还能够避免以前提到的AOF程序的bug。

2、线上redis主从环境下的持久化策略
描述:
以前线上项目使用redis,部署了redis主从环境。redis的主从复制功能很是强大,一个master能够拥有多个slave,而一个slave又能够拥有多个slave,如此下去,造成了强大的多级服务器集群架构。因为主redis采用了AOF和save快照的持久化,长时间下去,aof文件不断增大,磁盘空间使用率逐渐暴增。
考虑到性能问题,须要对redis持久化作些调整,调整以下:
   一、主库不开启AOF持久化,并关闭save快照功能(即注释默认的三个save设置),只在每晚12点定时手动作一次bgsave快照,并将快照文件转移到异地。即主库上不产生appendonly.aof持久化文件,作的快照数据放在.rdb文件里(如dump.rdb,因为是压缩配置(rdbcompression yes表示快照文件要压缩),因此快照文件要比aof文件小),而后将这个快照文件dump.rdb转移到其余的服务器上,防止主服务器宕机形成的损失!
   二、从库开启AOF持久化并1秒落地,一样不作快照save。并在每晚12点作一次bgrewriteaof压缩appendonly.aof持久化文件,压缩前先对aof文件进行备份。
--------------------------------------------------------------------------------------------------------------------------------------------
按照这种方法进行redis持久化调整,因为线上redis的主库以前采用了AOF和save快照的持久化,以后将这两种都关闭,从库采用AOF持久化。出现了下面的现象:
就是主库关闭AOF和save快照后,主redis上的appendonly.aof持久化文件在一段时间内还在刷,在增大,这是正常的,因为以前开启的缘故,刷过一段时间,主redis的appendonly.aof持久化文件就不刷了,只有从redis的appendonly.aof持久化文件在刷了
--------------------------------------------------------------------------------------------------------------------------------------------

主从redis部署的主要目的:数据持久化,灾难恢复,冗余。主库不落地,减小消耗。
一、主库不作AOF,不作快照,容许从库访问便可。
二、从库开启AOF,不作save
配置:

1、主库配置:
关闭save开展,aof默认不开启:
#save 900 1
#save 300 10
#save 60 10000
容许从库访问:
#bind 192.168.71.229
主库设置了密码访问:
requirepass password
2、从库配置:
开启AOF持久化:
appendonly yes
appendfsync everysec
appendfilename appendonly.aof
设置主库密码:
slaveof <masterip> <masterport>

验证:

主节点:
./redis-benchmark -c 100 -n 100000 -r 10000 -q -a password
./redis-cli -a password dbsize
从节点:
./redis-cli  dbsize
数量同样就是同步成功

灾难恢复:

一、主库故障,快速恢复到最近状态描述:主库挂了(redis程序挂了/机器宕机了),从库正常,

恢复到主库挂掉的时间点:去从库手动作一次快照,拷贝快照到主库相应目录,启动,OK。

注意: 

一、若主库挂了,不能直接开启主库程序。若直接开启主库程序将会冲掉从库的AOF文件,这样将致使只能恢复到前一天晚上12的备份。

二、程序在跑时,不能重启网络(程序是经过网络接口的端口进行读写的)。网络中断将致使中断期间数据丢失。

三、肯定配置文件所有正确才启动(尤为不能有数据文件名相同),不然会冲掉原来的文件,可能形成没法恢复的损失。

相关文章
相关标签/搜索