RDB是Redis持久化数据的一种方式,是执行时间点的Redis内存快照,redis数据还原时加载rdb文件,Redis的主从数据同步也是基于RDB实现的。redis
RDB流程:安全
1)执行bgsave命令,Redis父进程判断当前是否存在正在执行的子进程,如RDB/AOF子进程,若是存在bgsave命令直接返回。服务器
2)父进程执行fork操做建立子进程,fork操做过程当中父进程会阻塞,经过info stats命令查看latest_fork_usec选项,能够获取最近一个fork操做的耗时,单位为微秒。app
3)父进程fork完成后,bgsave命令返回“Background saving started”信息并再也不阻塞父进程,能够继续响应其余命令。性能
4)子进程建立RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。执行lastsave命令能够获取最后一次生成RDB的时间,对应info统计的rdb_last_save_time选项。spa
5)进程发送信号给父进程表示完成,父进程更新统计信息,具体见info Persistence下的rdb_*相关选项。操作系统
AOF是Redis持久化数据的另外一种方式,这种方式以日志形式记录每一条操做,当redis恢复数据时,还原全部操做。线程
AOF流程:日志
1)全部的写入命令会追加到aof_buf中。blog
2)AOF缓冲区根据对应的策略向硬盘作同步操做。
3)随着AOF文件愈来愈大,须要按期对AOF文件进行重写,达到压缩的目的。
4)当Redis服务器重启时,能够加载AOF文件进行数据恢复。
AOF缓冲区同步文件策略(配置appendfsync参数)说明:
always:命令写入aof_buf后调用系统fsync操做同步到AOF文件,fsync完成后线程返回
everysec:命令写入aof_buf后调用系统write操做,write完成后线程返回。fsync同步文件操做由专门线程每秒调用一次
no:命令写入aof_buf后调用系统write操做,不对AOF文件作fsync同步,同步硬盘操做由操做系统负责,一般同步周期最长30s
配置为always时,每次写入都要同步AOF文件,在通常的SATA硬盘上,Redis只能支持大约几百TPS写入,显然跟Redis高性能特性背道而驰,不建议配置。
配置为no,因为操做系统每次同步AOF文件的周期不可控,并且会加大每次同步硬盘的数据量,虽然提高了性能,但数据安全性没法保证。
配置为everysec,是建议的同步策略,也是默认配置,作到兼顾性能和数据安全性。理论上只有在系统忽然宕机的状况下丢失1秒的数据。
(策略选择根据业务不一样进行选择)
系统调用write和fsync说明:
write操做会触发延迟写(delayed write)机制,Linux在内核提供页缓冲区用来提升硬盘IO性能,write操做在写入系统缓冲区后直接返回,同步硬盘操做依赖于系统调度机制,例如:
缓冲区页空间写满或达到特定时间周期。同步文件以前,若是此时系统故障宕机,缓冲区内数据将丢失。
fsync针对单个文件操做(好比AOF文件),作强制硬盘同步,fsync将阻塞直到写入硬盘完成后返回,保证了数据持久化。
子进程经过fork操做产生,占用内存大小等同于父进程,理论上须要两倍的内存来完成持久化操做,但Linux有写时复制机制(copy-on-write)。父子进程会共享相同的物理内存页,当父进程处理写请求时会把要修改的页建立副本,而子进程在fork操做过程当中共享整个父进程内存快照。避免在大量写入时作子进程重写操做,这样将致使父进程维护大量页副本,形成内存消耗。
Linux kernel在2.6.38内核增长了Transparent Huge Pages(THP),支持huge page(2MB)的页分配,默认开启。当开启时能够下降fork建立子进程的速度,但执行fork以后,若是开启THP,复制页单位从原来4KB变为2MB,会大幅增长重写期间父进程内存消耗。建议设置“sudo echonever>/sys/kernel/mm/transparent_hugepage/enabled”关闭THP。
RDB和AOF对比:
RDB文件紧凑小巧,RDB文件生成又子进程完成,不会阻塞主进程,而且能够利用多核CPU资源,数据的恢复速度也比AOF快,可是RDB方式容易丢失数据,有些公司为了充分利用CPU资源,将Redis进程与cpu核心进行绑定,进行RDB时子进程与父进程会发生资源竞争,影响服务吞吐。
AOF更加安全,能够将数据更加及时的同步到文件中,可是AOF须要较多的磁盘IO开支,AOF文件尺寸较大,文件内容恢复数度相对较慢。
下一篇会介绍主从复制流程