redis持久化
redis虽然是基于内存的数据库,但也是支持持久化的,主要是用于重启机器、机器故障之后恢复数据,或数据同步之类的需求.
redis实现持久化主要有下面两种方式。
RDB
快照方式,redis默认的持久化方式,redis生成快照文件来纪录在当前时间点,redis中的数据,redis发生重启之后可以使用RDB文件进行恢复,在redis。conf
配置文件中默认有此下配置
save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发bgsave命令创建快照。
save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发bgsave命令创建快照。
save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发bgsave命令创建快照。
除了上述参数,在退出redis的时候会自动执行bgsave命令
redis提供了两种命令来生成RDB文件
save:同步保存操作,会阻塞 Redis 主线程;
bgsave:fork 出一个子进程,子进程执行,不会阻塞 Redis 主线程,默认选项,在fork的过程中如果有写命令进来,主进程会复制一份数据,进行写操作,原数据只读(copy on write)
bgsave执行流程
- 检查此时系统是否存在RBD/AOF的子进程正在执行,如果存在,返回错误。
- 执行fork操作,复制出子进程,在执行fork时主进程阻塞
- fork完毕,子进程执行生存RBD文件,主进程恢复工作,此时如果有写命令,采用写时复制的方法执行写命令(copy on write)
- 子进程执行完毕,通知父进程更新信息
RBD的缺点
1.两次执行之间有间隔,存在数据丢失风险
2.fork子进程,压缩,写出文件都比较耗时
AOF
AOF(append only file) ,每执行一条写命令,都追加记录到AOF缓冲区,然后再写到AOF文件中,最后再根据持久化方式刷新到磁盘中,只有同步到磁盘中才算持久化保存了,否则依然存在数据丢失的风险,比如说:系统内核缓存区的数据还未同步,磁盘机器就宕机了,那这部分数据就算丢失了。
AOF执行流程
- (append)所有命令追加到AOF缓冲区
- (write)将 AOF 缓冲区的数据写入到 AOF 文件中,用
write
函数将数据写入到了系统内核缓冲区之后直接返回了。 - (fsync)AOF 缓冲区根据对应的持久化方式,同步数据到硬盘,会阻塞到写入完成。
- (rewrite)如果AOF文件太大,需要定期对AOF文件重写
- (load)redis重启之后可以使用AOF文件进行恢复
AOF持久化方式
- appendfsync always:主线程用
write
函数将数据写入到了系统内核缓冲区之后,立即fsync同步到磁盘。性能消耗太大 - appendfsync everysec:主线程用
write
函数将数据写入到了系统内核缓冲区之后,每一秒执行一次fsync - appendfsync no:主线程用
write
函数将数据写入到了系统内核缓冲区之后,不执行fsync,让系统自己决定什么时候进行fsync
一般采用appendfsync everysec方式进行同步,如果发生故障最多会丢失一秒的数据
AOF缺点
- 生成的文件大于RDB,过大时需要重写
- 恢复时没有使用RDB文件快
- AOF开启后,支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的