05-持久化

nobility 发布于 2022-10-30 584 次阅读


持久化

持久化方式

  • 快照方式:将数据库中的所有数据全部拷贝出来,即某时刻的完整备份
    • 缺点:耗时耗性能,在拷贝时若又有写入数据时,新写入的数据不会保存
    • 优点:备份文件体积小,恢复速度快
  • 写日志方式:将数据库中数据的更新记录在日志中,需要将数据恢复时,根据日志文件记录的更新操作进行数据恢复
    • 缺点:备份文件体积大,恢复速度慢
    • 优点:性能损耗小,不会丢失数据(是否丢失数由备份策略决定)

若两种方式共存时,由于快照方式是一个较重的操作,写日志方式是一个较轻的操作,所以写日志方式优先级会高于快照方式

RDB

是快照方式,将Redis内存中存储的所有数据写入到一个RDB文件(二进制)中,恢复时加载这个RDB文件即可

要注意,若已存在老的RDB文件,会先创建一个临时文件,当备份命令执行完毕后再对老文件进行替换

RDB方式备份的三种方式

  • 同步备份:save命令,该命令执行时会阻塞其他命令执行,因为Redis是单线程,该命令在主进程中执行
  • 异步备份:bgsave命令,该命令执行时一般不会阻塞其他的命令,因为该命令会调用Linux系统函数fork()函数创建一个子进程(有可能在调用fork()方法时阻塞,因为创建子进程也需要内存和时间,子进程名为redis-rdb-bgsave),由子进程来完成备份操作,之后子进程再通知主进程
  • 自动备份:根据配置文件中配置的备份策略使用bgsave命令进行自动备份
    • 全量复制:主从Redis节点在进行全量复制时(主节点会执行bgsave)也会自动生成RDB文件
    • debug reload:执行该命令进行热重启,保存数据为RDB文件,清空数据库,在重新加载RDB文件
    • shutdown save:关闭数据库并保存数据为RDB文件

自动备份配置参数

配置项 描述 默认值
save 自动保存策略,第一个参数是时间(单位秒),第二个参数是修改量,比如save 900 1就代表在900秒内更新过一次数据就触发自动保存,可同时配置多条,若满足任意一条策略就会执行自动备份 900 1、300 10和60 10000
dbfilename 自动备份的文件名(仅仅只是名,可使用内置常量命名,比如${port}代表端口号) dump.rdb
dir Redis的工作目录(产生各种的文件的存放目录) ./
stop-writes-on-bgsave-error 若备份过程中发生错误是否停止写入 yes
rdbcompression RDB文件是否采用压缩格式 yes
rdbchecksum 是否对RDB文件进行校验和的检验 yes

AOF

是写日志方式,实质是将写命令写在硬盘的缓冲区中,再根据相关策略刷新到AOF文件中,恢复时加载这个AOF文件即可

AOF备份的三种策略

  • always:执行每条写命令都会将写命令写到AOF文件中,一定不会丢失数据,但是IO开销大

  • everysec:每秒将数据从缓冲区刷到AOF文件中,会适当的保护磁盘,可能会丢失一秒的数据

  • no:写命令何时刷新的AOF文件中,由操作系统来决定,所以不可控

AOF备份的配置参数

配置项 描述 默认值
appendonly 是否开启AOF备份 no
appendfilename 自动备份的文件名(仅仅只是名,可使用内置常量命名,比如${port}代表端口号) appendonly.aof
appendfsync 备份策略 everysec
dir Redis的工作目录(产生各种的文件的存放目录) ./
aof-load-truncated 在使用AOF恢复时,当AOF文件出现错误是否忽略 yes

AOF重写

写日志方式存在一个问题,就是随着时间的推移,日志文件会越来越大,对于同一数据的更新,只有最后那一次才起作用,所以需要将一些无用的命令日志进行化简,化简成一个很小的日志文件,从而能减少日志文件大小,也能加快恢复速度

并非扫描日志文件进行优化,而是对数据库本身进行回溯成AOF文件,为了防止在重新时有新的数据更新请求,会将新的更新请求日志先记录在缓冲区中,当重新完成后,再将缓冲区中的内容添加到重写后的AOF文件中

  • bgrewriteaof命令:该命令会创建一个子进程,由子进程来完成AOF重写操作
  • 自动重写:通过配置文件配置配置的策略进行自动重写(使用bgrewriteaof命令进行自动重写)

自动重写配置参数

配置项 描述 默认值
no-appendfsync-no-rewrite 在执行重写时是否不进行AOF操作,即是否绕过缓冲区,在重写时可能会丢失数据 no
auto-aof-rewrite-min-size AOF文件到达多大时重写 64mb
auto-aof-rewrite-percentage 据上一次重新增加了百分之多少后重写(单位百分比) 100

执行info persistence查看数据库持久化的具体信息

描述
aof_current_size AOF文件当前尺寸(单位字节),AOF启用状态才会有此参数
aof_base_size AOF上次启动和重写的尺寸(单位字节),AOF启用状态才会有此参数

持久化中的常见问题

fork操作

在异步备份时Redis主进程都会通过LInux中的fork()系统函数创建一个子进程,创建子进程的过程是同步的,可能会引起阻塞,使用info stats命令可查看数据库状态,其中latest_fork_usec项就是之前最近的fork所消耗的时间,单位微秒

导致fork操作慢的原因与机型、内存量有关,一般内存越大,耗时越长,因为内存越大内存页的数据也会也多,fork在寻找可用内存空间也会越耗时

提升fork操作的性能方式有:使用更好支持fork操作的机型、控制Redis实例最大可用内存、合理的配置Linux内存分配策略、甚至降低fork操作的频率

子进程

CPU

开销:RDB和AOF都会生成文件,属于CPU密集型

优化1:不要Redis绑定在一个CPU上,父子进程就会减少CPU竞争

优化2:不和CPU密集型的应用部署在同一台服务器上,减少与其他应用的CPU竞争

优化3:避免在单机多部署的场景大量发生AOF重写

内存

开销:理论上子进程的占用内存应该等于父进程,但是Linux有一个copy-on-write机制,该机制是父子进程共享物理内存页,但是当父进程写请求的时候会创建一个副本,此时会消耗内存,即父进程在大量写入的时候,子进程开销会比较大,因为创建副本

优化1:Linux内核的2.6.38版本中增加了THP的特性,支持大的内存页的分配,对于Redis来说大内存页会降低性能,使用echo never > /sys/kernel/mm/transparent_hugepage/enabled命令进行关闭该特性

优化2:避免在单机多部署的场景大量发生AOF重写

硬盘

开销:RDB与AOF文件的写入

优化1:不要和高硬盘负载服务部署在一起,例如存储服务、消息队列

优化2:将Redis配置no-appendfsync-on-rewrite配置项为yes,即在执行重写时不进行AOF操作,减少硬盘写入

优化3:使用固态硬盘

AOF追加阻塞

Redis在进行AOF备份时,主线程将更新命令放入缓冲区,由同步线程将缓冲区刷入AOF文件中,为了保证AOF文件的安全性,主线程会记录同步时间,并比对上一次同步时间,若超过两秒就会阻塞,保证同步完成

  • 可以通过Redis日志快速定位该问题:若出现Asynchronous AOF fsync is taking too long (disk is busy?),表示出现了该问题
  • 也可以通过info persistence命令进行查看:每发生一次追加阻塞,aof_delayed_fsync项就会加1

优化方式就是上述的硬盘优化

此作者没有提供个人介绍
最后更新于 2022-10-30