redis快照与AOF

咱们知道,redis的数据是保存在内存里,而内存一断电就没了,因此为了数据持久化,咱们得想办法把内存中的数据持久化到硬盘或者另外一台机子上。


先说本地持久化到硬盘,这就有两种方式,一是快照(snapshotting),二是只追加文件(append-only file AOF)redis

快照

快照的核心原理就是把redis在某个时间内存内的全部数据都写入硬盘,那么何时写入呢?快照的配置都有哪些呢?
出现下面的状况redis会快照内存里的数据
1 用户发送bgsave命令(此时redis会fork一个子进程,子进程负责生成硬盘文件,父进程负责继续接受命令)
2 用户发送save命令(和bgsave命令不一样,发送save命令后,到系统建立快照完成以前系统不会再接收新的命令,换句话说save命令会阻塞后面的命令,而bgsave不会)
3 用户在配置文件了配置了相似这样的命令 
  save 60 1000
  这个的意思是说,自从上次快照成功算起,若是知足"60秒内有1000次写入"这个条件,系统就自动调用bgsave,若是配置文件里有多个save命令,只有知足一个就调用bgsave命令
4 用户发送shutdown,系统会先导员save命令阻塞客户端,而后关闭服务器
5 当有主从架构时,从服务器向主服务器发送sync命令来执行复制操做时,只有主服务器当时没有进行bgsave操做,那么主服务器就会执行bgsave操做。更多的关于主从复制的信息,见下文

数据库

快照的配置信息

save 60 1000           
stop-writes-on-bgsave-error no
rdbcompression yes
dbfilename dump.rdb
dir ./
第一个配置不用解释了,第二个看英文就是失败后是否暂停写命令,第三个写的时候是否压缩,第五和第四合起来构成了数据文件的全地址


加入下午3:12分完成了一次快照,一切OK,在4:25开始进行第二次快照,持续了2分钟,一直到4:27次成功生成快照文件。在这2分钟内,系统又更新了35个键。若是在这2分钟内系统发生了崩溃,那么咱们就丢失了自3:12之后的全部数据。若是系统在刚完成快照且那35个键尚未写入硬盘时就崩溃了,那咱们就丢失了35个键。缓存

快照的优点

快照的文件适合备份
咱们创建下面的文件,让他天天凌晨3点执行,就能得到天天redis的版本了安全

[plain]  view plain  copy
 
  1. #! /bin/bash  
  2.    
  3. PATH=/usr/local/bin:$PATH  
  4. redis-cli SAVE  
  5.    
  6. date=$(date +"%Y%m%d")  
  7. cp /var/lib/redis/6379/dump.rdb /data01/cache_backup/$date.rdb  
  8.    
  9. echo "done!"  

快照的劣势

可能会丢失数据
save 60 1000,若是我在60秒内只更新了800条数据,而后系统崩溃了,那么这800条数据就没了
第二:
大数据量的时候,作RDB,redis服务会暂停近1分钟(20g的物理内存,redis里面有13g的数据)!这个就是redis持久化的时候的服务暂停现象(为啥?建立子进程,子进程的工做不须要资源么?)。
一种方式就是,我关闭自动快照的设置,就是不要写save 10 1000这样的命令,而是在系统不忙的时候发送bgsave,至少我能控制何时系统发生停顿么。再或者我发送save,这个虽然会停顿,可是由于不用建立子进程有时候也比较快。

bash

AOF

还有一种就是aof
这是什么呀?就是系统会把全部的redis数据进行的写操做的命令记录到硬盘上,这样一来恢复的时候,再执行一次命令就OK了
它有下面几个设置属性
appendonly no    #是否开启aof 
appendfsync everysec  
no-appendfsync-on-rewrite no
这个配置项是设置在rewrite的时候是否对新的写操做进行fsync(将缓存中的命令写入硬盘)。no表示进行fsync,yes表示不进行默认是设置为no
rewrite是将写操做合并,好比set aa 1; set aa 2; 两个操做应该写成一个操做set aa 2;而何时进行rewrite呢?就是aof文件太大的时候
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
appendfsync有三种选择分别是always,everysec,no
always就是每次有一个写命令,就把命令存的硬盘文件里
everysec就是每秒写入硬盘一次
no就是由操做系统来确认何时写
咱们通常都使用everysec,每秒把写命令写入到硬盘与不进行任何持久化操做在性能上没有什么区别。
aof优点在于:就算出问题了,最多丢失1秒内的更新数据
aof的劣势:
aof文件的体积可能会很大(可能比快照文件还大),另外一方面,系统重启的时候回从aof里读命令,若是aof文件太大,读命令也就要还好久

怎么办?系统能够重写aof文件,尽可能把文件体积缩小
不太重写的操做也是系统fork一个进程作的,那么在快照里存在的内存占用与性能问题,也会存在。
no-appendfsync-on-rewrite
这个配置项是设置在rewrite的时候是否对新的写操做进行fsync。no表示进行fsync,yes表示不进行
默认是设置为no
重写的时候,get操做是没有问题的,可是若是no-appendfsync-on-rewrite为no,那么写数据就会出现延迟。
咱们把no-appendfsync-on-rewrite改为yes,写就没有延迟了

也就是说,aof也是由问题的
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
上面这个两个命令的意思是当如今的aof文件大于64mb,且如今的文件比上一次重写后的文件体积增长了至少100%,那么就马上重写aof文件。



RDB 和 AOF ,我应该用哪个?
通常来讲,若是想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。若是你很是关心你的数据,但仍然能够承受数分钟之内的数据丢失, 那么你能够只使用 RDB 持久化。有不少用户都只使用 AOF 持久化, 但咱们并不推荐这种方式: 由于定时生成 RDB 快照(snapshot)很是便于进行数据库备份, 而且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快, 除此以外, 使用 RDB 还能够避免以前提到的 AOF 程序的 bug 。由于以上提到的种种缘由, 将来咱们可能会将 AOF 和 RDB 整合成单个持久化模型。 (这是一个长期计划。)
(上面两段,复制自:https://my.oschina.net/davehe/blog/174662)

同时使用快照与aof时,当 Redis 重启时, 它会优先使用 AOF 文件来还原数据集, 由于 AOF 文件保存的数据集一般比 RDB 文件所保存的数据集更完整。服务器

相关文章
相关标签/搜索