一、RDB
- RDB时会fork一个子进程,fork时会阻塞,子进程和父进程共享内存空间。
- RDB期间操作数据,采用写时复制技术,主进程会复制出页进行操作
RDB的优点
- RDB是二进制文件暂用的空间很小,RDB文件恢复比AOF快
- RDB可以用于数据备份以及数据恢复
- RDB有fork的子进程完成保存工作,主进程不需进行任何磁盘操作
RDB的缺点
- RDB默认5分钟备份一次,宕机后数据恢复会损失5分钟的数据
- Redis数据很大时,fork会存在明显的阻塞
- RDB采用写时复制,时如果写入很频繁,那么主进程会不断的复制页去操作,极端情况会全部复制,占用内存为原来的两倍
- 可读性很差
二、AOF
- AOF是通过保存redis所有写操作命令来记录数据库的状态,启动服务时,通过执行这些命令来回放数据
AOF步骤:
- 命令追加:redis执行完一个写命令时,将指令追加到aof缓冲区的尾部
- 文件写入:将缓冲区的数据写入aof文件,写入的是页缓存
- 文件同步:执行fsync / fdatasync 命令将页缓存进行文件同步,即刷盘
AOF参数:
- always:处理每个写命令都会从缓冲区写入AOF文件,并刷盘
- everysec:将缓冲区的命令都写入AOF文件,如果上次文件同步已经超过1秒,异步开启其他线程进行刷盘
- no:将缓冲区的命令写入AOF文件,不进行刷盘。何时刷盘有系统决定
AOF优点:
- AOF一般每秒进行一次刷盘,相比较RDB,服务宕机最多损失一秒钟的数据
- AOF文件过大时会进行重写,重写的数据是安全的,会在新的文件上重新,包含当前数据集的最小命令集合,当新文件写完后会替换旧文件
- AOF文件的可读性更强
AOF缺点:
- AOF文件比RDB更大,恢复更慢
- AOF一般默认1秒钟进行刷盘,所以比RDB慢
AOF为什么重写:
- 随着指令的执行,AOF文件会越来越大,对宿主主机造成影响,同时AOF回放就越慢。重写会开启子进程去写新的文件
AOF重写存在的问题以及解决:
- AOF重写时,客户端继续执行,把原来的数据修改,使得重写前后的文件数据不一致。解决方法是引入了重写缓冲区,在重写时开启,当重写时有新的命令追加会写入aof缓冲区和重写缓冲区,重写完成将重写缓冲区的命令追加到新的AOF文件中
AOF重写缓冲区内容过多怎么办:
- 重写完成后,主进程会将重写缓冲区的数据追加到新的AOF文件,这个过程是阻塞的,如果重写缓冲区内容过多阻塞时间会很长
- 解决方法:在主进程和子进程之间增加管道,同时增加一个文件事件,文件事件会将重写缓冲区的内容发送给子进程。子进程重写完成时,轮询等待可读事件1ms,20次没有读取到数据就结束,保证尽可能的读取更多的数据。
AOF重写流程图
三、混合持久化
- redis 4.0之后引入,发生在AOF文件重写时,前半段为RDB文件后半段为AOF增量数据。
- 当AOF发生重写时,主进程先fork出子进程对当前全部数据生成RDB文件,然后将增量数据写入AOF文件。最后将含有RDB格式和AOF格式的AOF文件替换旧的AOF文件
为什么引入混合持久化:
- 如果使用RDB文件最为持久化,会丢失很大数据,使用AOF持久化,AOF文件很大时,数据恢复会很慢
混合持久化的优点:
- 使用混合持久化即保证了数据的最多损失1秒,同时保证了恢复的速度远远快于AOF
混合持久化的缺点:
- RDB文件可读性差