乐趣区

关于redis:AOF和RDB

背景

咱们都晓得,Redis 是一个内存数据库,数据保留在内存中,访问速度是相当快的。
然而内存中的数据,服务器每次重启之后就会失落,redis 是如何做到长久化的呢?redis 长久化设计有哪些奇妙之处呢?
目前,Redis 的长久化次要有两大机制,即 AOF(Append Only File)日志和 RDB 快照。

AOF

格局

咱们以 Redis 收到“set testkey testvalue”命令后记录的日志为例,看看 AOF 日志的内容。其中,“*3”示意以后命令有三个局部,每局部都是由“$+ 数字”结尾,前面紧跟着具体的命令、键或值。这里,“数字”示意这部分中的命令、键或值一共有多少字节。例如,“$3 set”示意这部分有 3 个字节,也就是“set”命令。

写入形式

AOF 里记录的是 Redis 收到的每一条命令,这些命令是以文本模式保留的,也就是说每一条命令都会生成一条 AOF 日志。
那么如果说这条命令是语法有误的命令呢?也会记录吗?
Redis 是先执行命令,把数据写入内存,而后才记录日志,如下图所示:

Redis 应用写后日志这一形式的一大益处是,能够避免出现记录谬误命令的状况

这样的 AOF 还是有危险的, 执行完命令后宕机了,AOF 失落, 如果 redis 作为数据库就会有数据失落的危险

三种回写策略

  • Always: 同步写回: 每个命令执行完, 立马同步到磁盘
  • Everysec: 缓冲区每秒写回磁盘
  • No: 操作系统管制

AOF 重写

AOF 重写后果其实就是 对旧日志文件中的多条命令,在重写后的新日志中变成了一条命令。

重写会影响主线程?

AOF 日志是由主线程写的,然而 AOF 重写的 过程是由后台子过程 bgrewriteaof 来实现的,这也是为了防止阻塞主线程, 然而 fork 子过程有可能会使主线程阻塞

  • Redis 主线程 fork 子过程时,内核须要创立用于治理子过程的相干数据结构, 子过程要拷贝父过程的页表, 这个过程耗时与 redis 实例的内存大小无关
  • 子过程会和主线程共享内存。当主线程收到新写或批改的操作时,主线程会申请新的内存空间,用来保留新写或批改的数据,如果操作的是 bigkey, 主线程会因为申请大空间而面临阻塞危险

RDB

RDB 是 redis 内存快照
两个命令来生成 RDB 文件:save、bgsave

  • save:在主线程中执行,会导致阻塞
  • bgsave:创立一个子过程,专门用于写入 RDB 文件,防止了主线程的阻塞

写时复制

bgsave 子过程是由主线程 fork 生成的,共享主线程的所有内存数据。bgsave 子过程运行后,开始读取主线程的内存数据,并把它们写入 RDB 文件
采纳写时复制策略, 主线程更新数据会拷贝数据正本, 在正本批改数据

fork 期间会阻塞父过程?

  • fork 实现之前,会阻塞父过程,次要是父过程须要拷贝过程中的内存页表给子过程,每个过程都要有本人的内存页表
  • 拷贝内存页表也须要破费工夫,过程占用的内存越大,拷贝工夫越久

个别采纳混合模式: 快照 +AOF 模式

退出移动版