您的位置:首页 > 数据库 > Redis

Redis数据持久化

2013-12-30 08:38 239 查看
Redis数据持久化
      RDB方式与AOF方式,可以单独用一种或两种结合。RDB方式相当于定时全备,AOF方式相当于重做日志。REDIS在RDB与AOF都开启的情况下,启动的时候会加载AOF,因为AOF持久化方式可能丢失的数据更少。

RDB方式
    这种持久化是通过快照完成的,当符合一定条件时Redis会自动将内存中的所有数据进行快照,并存储在硬盘上。
    进行快照的条件由两个参数构成:save <seconds> <changes>
    多个save条件之间是“或”的关系,seconds与changes之间是“与”的关系。
    当条件为真,块照会被触发,然后在dir参数定义的目录,以dbfilename参数定义的文件名(一般是dump.rdb)保存下来。
    举例:
    save 900 1         #900秒内1个key被改动
    save 300 10       #300秒内10个key被改动
    save 60 10000   #60秒内10000个key被改动
    时间最大的一个save后必须是1,假如是比1大的值,比如2,那么只要我每900秒内只改动1个key,那么就永远不会触发快照。
    如果想取消这种持久化方式,所有SAVE参数删除或用一条save ""即可。

快照过程:
1. Redis函数使用fork函数赋值一份当前进程的副本(子进程);
2.父进程继续接收并处理客户端发来的命令,而子进程开始将内存中的数据写入硬盘中的临时文件;
3.当子进程写完所有数据后,会用临时文件替换RDB文件,至此一次快照操作完成。

注意:

只有快照结束才会将旧的文件替换成新,所以任何时候RDB文件都是完整可用的。
新的RDB文件是开始执行fork一刻的内存数据。
RDB文件是经过压缩的,可以通过配置rdbcompression参数为no以禁用压缩、以节省CPU资源,压缩后的文件更小更利于传输。
可以手动用SAVE命令或BGSAVE命令让Redis执行快照,前者由主线程做快照会堵塞其他请求,后者通过fork出子进程进行。
Redis启动后会读取RDB快照文件,将数据从硬盘载入内存,一般一千万个string,1G的快照需要20-30秒。

查看fork出的子进程
[ldh@hauser redis-2.8.3]$ redis-cli -p 6389 -a pass1234 bgsave && ps -ef | grep redis
Background saving started
ldh 31080 30072 0 11:46 pts/3 00:00:00 redis-server *:6389
ldh 31304 31080 0 11:53 pts/3 00:00:00 redis-rdb-bgsave *:6389 

AOF方式

    开启AOF持久化后,每执行一条会更改Redis中数据的命令,Redis就会将该命令写入硬盘中的AOF文件。这种写是异步的,通过后台进程处理。默认情况下AOF方式没有开启,可以通过appendonly参数设为yes来开启。AOF文件的保存位置和RDB文件位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof,可以通过appendfilename参数修改。
    事实上,appendonly.aof是纯文本格式,打开后也能轻易看懂我们做过的操作。随着执行命令的增多,AOF文件会变得越来越大。所以我们希望删除其中没用的条目。
例如
set foo 1
set foo 2
set foo3
第3条的效果会覆盖前两条,我们只需要保留第三条即可。实际上,我们通过设置这两个参数,来使文件达到条件就自动重写。
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
实例启动后,会记得首次rewrite完后文件大小。例如是100mb,那么下次要到200mb,我们才超出100%,才会rewrite。如果实例启动以来还没rewrite过,那么启动时文件多大,就作为上次rewrite数。
这里为了防止文件太小也rewrite,例如上次是10mb,这次到了20mb就rewrite,规定了必须得到64mb以上才能进行rewrite操作。将percentage设为0,可以禁用rewrite特性。
其实rewrite的时候,调用的命令是BGREWRITEAOF,我们也可以手工调用它来执行rewrite。rewrite完后,冗余的数据就被删除了。启动时,redis会将AOF文件中的每条命令载入内存,可以想象,速度肯定比RDB会慢一些。

缓存同步
上述所谓的写到条目写到aof文件,往往其实只是写到OS的缓存。默认情况下系统30秒执行一次同步操作,以便将缓存真正写入磁盘。难道我们AOF必须忍受最高30秒内的数据损失?我们通过appendfsync参数设置同步时机。在一定时机,redis会用fsync()系统调用来通知系统将缓存同步到磁盘。
# appendfsync always  --aof文件每有写入就通知系统同步缓存
appendfsync everysec  --每秒,安全性与快捷性的折衷
# appendfsync no        --交给OS自己决定同步缓存时机
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: