一、持久化的作用1、什么是持久化(Persistence),即将数据(如内存中的对象)保存到永久性存储设备(如磁盘)中。持久化Redis中的所有数据都保存在内存中,数据的更新会异步保存到磁盘中。2.持久化的实现快照持久化快照持久化就是在某个时刻对所有数据进行完整的备份。例子:Mysql的dump方法,Redis的RDB方法。日志写入方式持久化日志写入方式持久化是将用户执行的所有写入命令(增删改查)备份到一个文件中。恢复数据时,只需重新执行所有备份命令即可。例子:Mysql的Binlog,Redis的AOF,Hbase的HLog。2.RDB1.什么是RDBRDB简介RDB持久化方法可以按指定的时间间隔存储数据的快照。默认情况下,Redis将数据库快照保存在名为dump.rdb的二进制文件中。当Redis运行时,RDB程序将当前内存中的数据库快照保存到一个磁盘文件中。当Redis重启时,RDB程序可以通过加载RDB文件来恢复数据库的状态。工作原理当Redis需要保存dump.rdb文件时,服务器会执行以下操作:Redis调用fork。同时具有父进程和子进程。子进程将数据集写入临时RDB文件。当子进程写完新的RDB文件后,Redis用新的RDB文件替换原来的RDB文件,并删除旧的RDB文件。这种工作方式让Redis受益于写时复制机制。2、RDB的三种主要触发机制save命令(同步数据到磁盘)save命令执行同步操作,将所有数据的快照以RDB文件的形式保存。127.0.0.1:6379>saveOK因为save命令是同步命令,所以会占用Redis的主进程。如果Redis数据很多,save命令的执行速度会很慢,阻塞所有客户端请求。因此在生产环境中很少直接使用SAVE命令,可以使用BGSAVE命令代替。如果BGSAVE命令保存数据的子进程出错,使用SAVE命令保存最新的数据是最后的手段。bgsave命令(异步保存数据到磁盘)bgsave命令执行一个异步操作,以RDB文件的形式保存所有数据的快照。127.0.0.1:6379>bgsaveBackgroundsavingstartedRedis利用Linux系统的fock()生成子进程将DB数据保存到磁盘,主进程继续提供服务供客户端调用。如果操作成功,可以通过客户端命令LASTSAVE查看操作结果。savevsbgsave命令savebgsaveIO类型同步异步阻塞?是是(阻塞发生在fock(),通常很快)复杂度O(n)O(n)优点不会消耗额外内存不阻塞客户端命令缺点阻塞客户端命令需要fock子进程,内存消耗自动产生另外为了手动对RDB执行save和bgsave命令来实现RDB的持久化,Redis也提供了自动生成RDB的方式。可以通过配置文件对Redis进行设置,使其在满足“N秒内数据集至少有M次变化”的条件时自动保存数据集。比如下面的设置会让Redis在满足“60秒内至少有1000个key被改变”的条件时自动保存数据集:save6010003RDB相关配置#RDB自动持久化规则#WhenWhenatleast900秒内更改1个key,自动保存数据集save9001#当300秒内至少更改10个key时,自动保存数据集save30010#当60秒内至少更改10000个key时,数据集为自动保存。save6010000#RDB持久化文件名dbfilenamedump-.rdb#数据持久化文件存放目录dir/var/lib/redis#bgsave出错时是否停止写入,一般为yesstop-writes-on-bgsave-erroryes#rdb文件是否使用压缩格式rdbcompressionyes#是否校验校验rdb文件,一般为yesrdbchecksumyes4。RDB的优点RDB是一个非常紧凑的文件,保存的是某个时间点的数据集,非常适合做数据集的备份,比如每小时可以保存过去24小时的数据,以及每天保存过去30天的数据,这样即使出现问题,也可以根据需要恢复到不同版本的数据集。RDB是一个紧凑的单一文件,很容易转移到另一个远程数据中心或亚马逊的S3(可能加密),非常适合灾难恢复。RDB保存RDB文件时,父进程只需要fork一个子进程,接下来的工作全部由子进程完成,父进程不需要做其他IO操作,所以RDB持久化方法可以最大化redis的性能。与AOF相比,RDB方式在恢复大数据集时会更快。5、RDB的缺点是耗时耗性能。RDB需要频繁的fork子进程将数据集保存到硬盘。当数据集比较大时,fork过程非常耗时,可能导致Redis无法在毫秒级内响应客户端请求。如果数据集很大,CPU性能不是很好,这种情况会持续1秒,AOF也需要fork,但是可以调整重写日志文件的频率,提高数据集的持久性。无法控制,丢失数据。如果您希望在Redis意外停止工作(例如断电)的情况下将数据丢失降至最低,那么RDB不适合您。虽然可以配置不同的保存时间点(比如5分钟一次,对数据集有100次写操作),但是Redis完整保存整个数据集是一个比较繁重的工作,一般设置为5分钟一次minutes或者更频繁地做一次完整的保存,万一Redis意外宕机,你可能会丢失几分钟的数据。3.AOF1。什么是AOF快照功能(RDB)不是很持久(durable):如果Redis因为某种原因宕机,服务器会丢失快照中尚未保存的最近写入的数据。从1.1版本开始,Redis增加了一种完全持久化的持久化方式:AOF持久化。可以在配置文件中开启AOF方式:appendonlyyes开启AOF后,每当Redis执行一条改变数据集的命令(如SET)时,这条命令就会追加到AOF文件的末尾。这样当Redis重启时,程序可以通过重新执行AOF文件中的命令来重建数据集。AOF工作原理-创建AOF工作原理-恢复2.AOF持久化的三种策略你可以通过配置文件来配置Redis多久将数据fsync到磁盘。每次将新命令附加到AOF文件时,总是执行fsync:非常慢且非常安全。everysec每秒fsync一次:速度足够快(与使用RDB持久化大致相同),并且在失败时仅丢失1秒的数据。推荐的(也是默认的)操作是每秒fsync一次。这种fsync策略提供了速度和安全性之间的平衡。noNeverfsync:将数据交给操作系统,由操作系统决定何时同步数据。更快,更不安全的选择。Always,everysec,no比较命令always不丢数据的优缺点,IO开销高,一般SATA盘每秒只有几百TPSeverysec和fsync,数据丢失最多1第二,数据可能会丢失1秒。)是每秒fsync一次,这种fsync策略可以兼顾速度和安全性。3、AOF重写由于AOF是通过不断的在文件末尾追加命令来运行的,所以AOF文件的大小也会随着写入命令的增多而越来越大。例如,如果你在一个计数器上调用INCR100次,AOF文件需要使用100个条目来保存计数器的当前值。然而在实际中,只需要一条SET命令就足以保存计数器的当前值,剩下的99条记录其实是多余的。为了应对这种情况,Redis支持一个有趣的特性:可以在不中断服务客户端的情况下重建AOF文件。执行bgrewriteaof命令,Redis会生成一个新的AOF文件,这个文件包含了重建当前数据集所需的最少命令。Redis2.2需要手动执行bgrewriteaof命令;Redis2.4可以通过配置自动触发AOF改写。AOF重写的作用减少磁盘占用加速数据恢复AOF重写bgrewriteaof命令的实现Redisbgrewriteaof命令用于异步执行一个AOF(AppendOnlyFile)文件重写操作。覆盖将创建当前AOF文件的卷优化版本。即使bgrewriteaof失败,也不会丢失任何数据,因为在bgrewriteaof成功之前不会修改旧的AOF文件。AOF改写由Redis自身触发,bgrewriteaof只是用来手动触发改写操作。具体内容:如果通过磁盘快照创建子Redis,AOF重写直到RDB终止才会被保存。在这种情况下,BGREWRITEAOF仍将返回OK状态代码。从Redis2.6开始,可以使用INFO命令查看AOF改写的执行情况。如果正在执行的AOF覆盖返回错误,则AOF覆盖将在稍后的某个时间点重新调用。AOFrewriteconfiguration配置名称含义auto-aof-rewrite-min-size触发AOF文件重写最小大小auto-aof-rewrite-percentage触发AOF文件重写增长率统计名称含义aof_current_sizeAOF文件当前大小(wordsSection)aof_base_sizesizeAOF文件的最后一次启动和重写的(字节)。AOF重写自动触发机制需要同时满足以下两个条件:aof_current_size>auto-aof-rewrite-min-size(aof_current_size-aof_base_size)*100/aof_base_size>auto-aof-rewrite-percentage假设Redis配置项为:auto-aof-rewrite-min-size64mbauto-aof-rewrite-percentage100当AOF文件的体积大于64Mb,并且AOF文件的体积比上一次重写时volume至少翻倍(100%),Redis会执行bgrewriteaof命令重写。AOF改写过程3.AOF相关配置#开启AOF持久化方式appendonlyyes#AOF持久化文件名appendfilenameappendonly-.aof#每秒同步一次缓冲区数据到磁盘appendfsynceverysec#数据持久化文件存放目录dir/var/lib/redis#执行重写时是否不同步数据到AOF文件#这里yes表示执行重写时不同步数据到AOF文件no-appendfsync-on-rewriteyes#触发AOF文件重写的最小大小auto-aof-rewrite-min-size64mb#触发AOF文件重写的增长率auto-aof-rewrite-percentage1004.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文件的内容很容易让人理解,也很容易分析(解析)文件。导出AOF文件也很简单:比如不小心执行了FLUSHALL命令,但是只要AOF文件没有被覆盖,那么只要停止服务器,去掉AOF文件末尾的FLUSHALL命令,即可重启Redis,数据集可以恢复到FLUSHALL执行前的状态。5、AOF的缺点对于同样的数据集,AOF文件的体积通常比RDB文件的体积要大。根据使用的fsync策略,AOF可能比RDB慢。总的来说每秒fsync的性能还是很高的,关闭fsync可以让AOF和RDB一样快,即使是在高负载下。但是,在处理巨大的写入负载时,RDB可以提供更有保障的最大延迟(latency)。四、RDB和AOF的选择1、RDB和AOF的比较-RDBAOF启动优先级低,体积大,体积小,恢复速度大,数据安全性快,数据丢失,数据丢失由策略决定。2、如何选择使用哪种持久化方式?一般来说,如果要达到媲美PostgreSQL的数据安全性,应该同时使用这两种持久化功能。如果你真的很在意你的数据,但仍然可以容忍数据在几分钟内丢失,那么你可以使用RDB持久化。很多用户只使用AOF持久化,但不推荐这种方式:因为定期生成RDB快照(snapshot)非常方便数据库备份,而且RDB恢复数据集的速度也比AOF恢复快。