Redis入门【九】---------持久化(快照与AOF)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Tacks/article/details/82706576

前言

redis(nosql产品)为了内部数据的安全考虑会把本身的数据以文件形式保存到硬盘中一份,在服务器重启后会把硬盘中的数据恢复到内存中,这个过程叫做持久化(persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。

redis提供两种不同的持久化方法来将数据存储到硬盘中,一个叫做快照(snapshotting),有的地方也叫Redis DataBase(简称RDB)它可以将存在于某一时刻的所有数据都写入到硬盘里面;另一个方法是只追加文件(append-only file,AOF),他在执行写命令的时候,将被执行的写命令复制到硬盘中。


快照持久化(RDB)

redis可以通过创建快照来获得存储在内存里面的数据在某个时间点的副本,在创建快照之后,用户可以对快照进行备份,可以将快照复制到其他的服务器从而创建具有相同数据的服务器的副本,还可以将快照留在原地,以便重启服务器的时候使用恢复。

看一下关于快照持久化的配置文件的选项

# 当在规定的时间内,Redis发生了写操作的个数满足条件,会触发发生bgsave命令。
# save <seconds> <changes>
#在900秒(15分钟)之后,如果至少有1个key发生变化,则dump内存快照。
save 900 1 
#在300秒(5分钟)之后,如果至少有10个key发生变化,则dump内存快照。          
save 300 10 
#在60秒(1分钟)之后,如果至少有10000个key发生变化,则dump内存快照。        
save 60 10000  

#是否启用rdb文件压缩,默认为“yes”,压缩往往意味着“额外的cpu消耗”,文件小,网络传输快
#(如果希望RDB进程节省一点CPU时间,设置为no,但是可能最后的rdb文件会很大)   
rdbcompression yes 
#redis持久化监控 是否在快照过程中报错
stop-writes-on-bgsave-error no
#在redis重启后,从rdb文件向内存写数据之前,是否先检测该rdb文件是否损坏
rdbcompression yes

#dbfilename:持久化数据存储在本地的文件
dbfilename     dump.rdb
#持久化数据存储在本地的路径
dir ./


​

创建快照的方法

1.bgsave

客户端可以向redis发送一个bgsave命令创建一个快照,基本上除了window平台,都支持。这种方式Redis会调用fork创建一个子进程,然后,子进程负责将快照写入硬盘,而父进程可以继续接受客户端的命令请求。

2.save

客户端也可以利用save命令来进行,创建快照。但是它于上一个bgsave命令不一样的是,接受到save的redis服务器,在创建快照完成之前,是不会再去响应其他的命令,也就是会阻塞到这里,直到快照创建完毕。它没有创建子进程,相对来说就节省内存,但是不太友好。

3.配置文件的save选项

也就是上面配置文件的前三个,比如save 60 10000,那么从Redis最近的一次快照之后算起,“当60s也就是一分钟内,如果有10000次的写入”,redis就会自动执行bgsave命令。看到上面的配置文件其实是有三个save配置,那么当这三个配置中save一个条件满足,就会执行,这个操作。那么会有人问,你60秒写入10000的操作,那么你300秒肯定有10的写操作,就是有一个包含关系,为什么还要多设置昵?其实是为了数据安全,数据变化快的话,备份频率就高一点(数据相对安全,负载高),数据变化慢,备份频率就低一点(服务器负载也低一点)。如果你只是配置了save 60 10000,那么我在60秒内写入9999个操作,那么你没有备份,到时候如果redis服务器突然宕机,那么数据的损失量就不好了。当然也可以全部注释掉save自动快照

4.接受到关机信号

例如当redis通过shutdown命令接受到关闭服务器的请求的时候,他会先进行save命令,然后阻塞所有的客户端,不再执行客户端发送的任何指令,并在快照完成后关闭服务器。

5.复制服务器(主从复制)

这个知识点,先总结到这里,关于复制以后再具体了解。如果一个redis服务器向另一个redis服务器连到一起,向对方发送sync的命令的时候,在开始复制操作的时候,如果主服务器没有进行bgsave操作或者不是刚执行好bgsave,那么主服务器,就会进行bgsave命令。

注意

压缩选项(rdbcompression):上面配置文件,对于rdb文件的压缩,是当字符串长度大于等于21个字节才会进行

校验选项(rdbchecksum)    :上面配置文件提到,在重启redis的时候,会检测文件是否损坏,那么这个check_sum(校验和)其实是一个存储在rdb文件最后的八个字节里面:看一下这个rdb文件的一个结构

redis(rdb文件标准) db_version(rdb文件版本号) databases(数据持久化核心) EOF(结束) check_sum(校验和)

该值是根据前边四部分值算出来的,在持久化的时候将该值算出来并写入rdb文件的末尾;在根据rdb文件恢复数据的时候,再根据rdb文件中的前边四部分值计算出一个校验和,然后与当前rdb文件中的check_sum(即后八个字节)的内容进行比对,如果一样,说明没损坏,如果不一样,说明前四部分有数据损坏(即该文件损坏)

关于RDB的文件恢复:自动的持久化数据存储到dump.rdb后。实际只要重启redis服务即可完成(启动redis的server时会从dump.rdb中先同步数据)


AOF持久化

redis可以通过AOF(append-only-file),简单来说,就是这种持久化是会将被执行写命令(例如增删改)追加到AOF文件末尾,这样来记录数据的变化,类似“日志”,记录了命令的历史写操作。当需要数据恢复的时候,可以直接replay文件就可以还原之前的写操作。当然这里的IO操作来追加文件写命令不是写一条就追加进去一条,写命令会先添加到缓冲区,然后操作系统会在某个时刻将缓冲区存储的内容写入硬盘。

 还是先来看一下配置文件中AOF相关选项:

#此选项为aof功能的开关,默认为“no”,可以通过“yes”来开启aof功能  
appendonly yes  
 
#aof文件的文件名称
appendfilename appendonly.aof  
#aof文件路径(和上面rdb文件路径是一个选项,也就是共用)
dir ./

#指定aof操作中文件同步策略,有三个合法值:always everysec no,默认为everysec 
appendfsync everysec  
#在aof-rewrite期间,appendfsync是否暂缓文件同步,"no"表示不暂缓,“yes”表示暂缓,
no-appendfsync-on-rewrite no  
 
#aof文件rewrite触发的最小文件尺寸(mb,gb),默认64mb
auto-aof-rewrite-min-size 64mb  
 
#相对于“上一次”rewrite,本次rewrite触发时aof文件应该增长的百分比。  
#每一次rewrite之后,redis都会记录下此时“新aof”文件的大小(例如A),那么当aof文件增长到A*(1 + p)之后  
#触发下一次rewrite,每一次aof记录的添加,都会检测当前aof文件的尺寸。  
auto-aof-rewrite-percentage 100

关于这些选项注意点:

appendonly : 修改为yes才可以使用AOF持久化

appendfsync : 同步策略/频率,也就是多久进行一些命令写入aof文件,有三个可选值

①always每一个命令,都立即同步到aof文件中去,很安全,但是速度慢,因为每一个命令都会进行一次磁盘操作,IO开支较大。会受到硬盘的限制,而且频繁的读写,可能会引起硬盘的寿命减少

②everysec每秒将数据写一次到aof文件,redis推荐的方式。如果遇到物理服务器故障,有可能导致最近一秒内aof记录丢失,可能为部分丢失。而且当硬盘忙于写入操作的时候,redis还会优雅的放慢自己的速度来适应硬盘的最大写入速度。

③no 将写入工作交给操作系统,由操作系统来判断缓冲区大小,统一写到aof文件,速度快,但是同步频率低,容易丢数据。

no-appendfsync-on-rewrite :在RDB持久化数据的时候,此时的aof操作是否停止,若为yes,则停止在停止的这段时间内,执行的命令会写入内存队列,等RDB持久化完成后,统一将这些命令写入aof文件 该参数的配置是考虑到RDB持久化执行的频率低,但是执行的时间长,而AOF执行的频率高,执行的时间短,若同时执行两个子进程(RDB子进程、AOF子进程)效率会低(两个子进程都是磁盘读写)但是若改为yes可能造成的后果是,由于RDB持久化执行时间长,在这段时间内有很多命令写入了内存队列,最后导致队列放不下,这样AOF写入到AOF文件中的命令可能就少了很多,在恢复数据的时候,根据aof文件恢复就会丢很多数据。 一般选择no就好。

auto-aof-rewrite-min-size  :重写/压缩aof文件,有些同学可能会想到,AOF如此好用,可以在短时间内定期进行持久化,那么如果写命令越来越多,aof是不是会越来越大,占据大量的硬盘资源,这个时候如果重启读取aof文件还原数据集,岂不是要很长时间;而且还有种极端的情况,就是不断的增加一个key的值,比如将sum不断做加一操作,那么写命令其实很多,这个时候如果将重复的写命令变成set直接修改成最后的值,不就好了。其实可以通过gbrewriteaof命令来进行AOF的文件的重写(Rewrite),这个命令其实也是个bgsave一样创建一个子进程来进行aof的重写。但是我们这个地方用这个选项来自动化配置aof文件重写,例如设置auto-aof-rewrite-min-size 64mb,那么当文件达到这个大小,它就会自己进行重写。

auto-aof-rewrite-percentage: rewrite触发时aof文件应该增长的百分比,可以设置100以上,这样redis可以在aof文件变的更大的情况下才去重写。


对比总结

无论是快照持久化,还是AOF持久化,将数据持久化到硬盘上都是必要的,但是除了持久化之外,用户还需要将持久化的文件备份。这样就可以防止因为系统重启或者崩溃的情况下,可以进行数据的恢复,使之数据的完整性越来越好。

快照持久化RDB

①灾难恢复,RDB是非常不错的选择。因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上。

②性能最大化,对于Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。但是,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。

③恢复效率高,启动效率高,RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

④运行效率高,RDB在运行效率上往往会高于AOF。总之,每秒同步策略的效率是比较高的,aof同步禁用策略的效率和RDB一样高效。

⑤文件体积小,对于相同的数据集来说,RDB 文件的体积通常要小于AOF 文件的体积 。

AOF持久化

①同步持久化,耐久(much more durable),AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,所以主线程可以继续努力地处理命令请求)。

②AOF 进行重写,如果日志过大,Redis可以自动启用rewrite机制。即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创 建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性。

③AOF文件易懂, AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。

参考网址

http://doc.redisfans.com/topic/persistence.html

 

猜你喜欢

转载自blog.csdn.net/Tacks/article/details/82706576
今日推荐