• java
  • go
  • 数据库
  • linux
  • 中间件
  • 书
  • 源码
  • 夕拾

  • java
  • go
  • 数据库
  • linux
  • 中间件
  • 书
  • 源码
  • 夕拾

redis宕机恢复

目录

  • 目录
  • aof
    • 写回策略
    • 日志太大与aof重写
      • aof重写过程
      • fork流程
      • aof重写时机
  • rdb
    • rdb文件的生成
  • 混合持久化

aof

数据库写日志是写前日志(write ahead log,wal),先把修改的数据写到日志里,然后故障时恢复,AOF日志是写后日志,redis先执行命令,然后记录日志。
传统的数据库日志,redo日志记录的是修改后的数据,而AOF是redis收到的每条命令。

写后日志得好处:

  1. 可以避免额外的语法检查开销
  2. 不会阻塞当前写操作。

风险:

  1. 如果刚执行完就宕机,如果只是用做缓存,还可以从数据库读取,但是如果直接用作数据库,则会造成数据丢失。
  2. aof日志也是在主线程执行,如果日志文件写入磁盘时,磁盘写压力大,会导致写盘很慢,导致后续操作阻塞。

写回策略

写回时机 优点 缺点
always 同步回写,每个命令执行完,立刻写回磁盘 基本不会丢数据 免会影响主线程性能.
everySec 每秒写回:每个命令执行完,只是先把日志写到aof文件缓冲区,每隔1s把缓冲区中的内容写入磁盘 在避免数据丢失和避免影响主线程之间做了折中 宕机1s内的数据会丢失.
no 操作系统控制写回,每个命令执行完,把写日志写到aof文件的缓冲区,由操作系统决定何时将缓冲区内容写回磁盘. 性能好 一旦宕机,丢失较多数据.

日志太大与aof重写

aof重写机制就是在重写时,redis根据数据库现状创建新的aof文件.将反复操作一个键值对的命令合并成一个.

aof重写过程

每次执行重写时,主线程fork出bgrewriteaof,fork会把主线程内存拷贝一份给bgreriteaof子进程.然后bgrewriteaof在不影响主线程的情况,逐一把拷贝到的数据写成操作,记入重写日志.

重写过程中,主线程仍然可以处理新来的操作,仍然会使用aof日志操作,这个操作也会写到重写日志的缓冲区.等待拷贝数据的所有记录重写完成后,重写日志记录的这些最新操作也写入新的aof文件,保证数据库最新状态的记录.之后可以用新的aof文件代替旧文件.

fork流程

fork出bgrewriteaof进程时会阻塞主线程,fork采用操作系统提供的写时复制(copy on write),为了避免一次性拷贝大量内存数据给子进程造成的长时间阻塞问题,但fork子进程需要拷贝进程必要的数据结构(内存页表,虚拟内存和物理内存的映射索引表),阻塞时间取决于整个实例的内存大小.但是拷贝完毕后,子进程,父进程仍然指向相同的内存地址空间.写实复制时发生在写时,才会真正拷贝真正的数据.有可能造成父进程阻塞. fork出的子进程指向与父进程相同的内存空间,此使子进程可以进行aof重写,把内存的数据写入到aof文件中,但是父进程仍然会有流量写入,如果父进程操作得是一个已经存在的key,那么这个时候父进程就会拷贝这个key对应的内存数据,申请新的内存空间,逐渐的进行数据分离,内存分配是以页为单位进行分配,默认4k,如果父进程此使操作得是一个bigkey,重新申请大块内存耗时会变长,可能会产生阻塞风险.如果操作系统开启了大页机制(huge page,2M),那么父进程申请内存时阻塞概率会大大提高,所以redis机器上需要关闭huge page 机制,redis每次fork生成rdb或aof重写完成后,都可以在redis log中看到父进程重新申请了多大的内存空间.

如果某个程序总是喜欢用fork,也建议关闭huge page机制

aof重写时机

AOF文件大小同时超出下面这两个配置项时,会触发AOF重写。

  1. auto-aof-rewrite-min-size,运行aof重写时文件的最小大小
  2. auto-aof-rewrite-percentage,当前AOF文件大小和上一次重写后AOF文件大小的差值,再除以上一次重写后AOF文件大小。也就是当前AOF文件比上一次重写后AOF文件的增量大小,和上一次重写后AOF文件大小的比值。
1
2
3
4
5
6
7

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

#这两个配置项的意思是,在aof文件体量超过64mb
#且比上次重写后的体量增加了100%时自动触发重写。我们可以修改这些参数达到自己的实际要求

rdb

RDB(Redis DataBase):记录某一时刻的数据.执行的是全量快照.

rdb文件的生成

redis提供了两个命令生成rdb文件,save与bgsave

  1. save:主线程执行,会阻塞
  2. bgsave:创建一个子进程,专门用来写入rdb文件,避免主线程的阻塞,redis rdb文件生成的默认配置.

混合持久化

开启参数

1
aof-use-rdb-preamble yes
jdk编译
es的简介
  1. 1. 目录
  2. 2. aof
    1. 2.1. 写回策略
    2. 2.2. 日志太大与aof重写
      1. 2.2.1. aof重写过程
      2. 2.2.2. fork流程
      3. 2.2.3. aof重写时机
  3. 3. rdb
    1. 3.1. rdb文件的生成
  4. 4. 混合持久化
© 2023 haoxp
Hexo theme