ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Redis两种持久化方式原理和单机多实例持久化脚本

2020-05-05 14:02:15  阅读:355  来源: 互联网

标签:aof 持久 AOF 单机 Redis rewrite RDB 进程 重写


注意:Linux系统使用redis需要更改系统的内存分配策略,执行sysctl vm.overcommit_memory=1命令,0-2分别代表不加载、加载、允许超额加载

一、RDB

RDB持久化是把当前数据生成二进制快照保存到硬盘的过程。

配置项:

  • dir:保存路径
  • dbfilename:保存文件名
  • rdbcompression:是否开启压缩,默认开启,可以方便保存到硬盘和发送给从节点

触发时机:

  • save:阻塞当前Redis服务器,直到RDB过程完成,线上不建议使用
  • bgsave:Redis主进程执行fork操作创建子进程,RDB持久化过程由子进程完成,阻塞只发生在fork阶段。
  • 配置save频率自动触发:save m n表示m秒内发生n次修改后自动触发bgsave
  • 从节点执行全量复制,主节点自动执行bgsave生成RDB文件并发送给从节点
  • 执行debug reload命令重新加载Redis时执行save
  • 如果没有开启aof,执行shutdown时回执行bgsave

触发流程:

  1. 执行bgsave命令,如果正在执行bgsave命令则直接返回
  2. 父进程执行fork操作创建子进程,fork操作时会阻塞主进程
  3. 父进程fork完后主进程不再阻塞,可执行其它命令
  4. 子进程创建RDB文件,写入完成后替换旧文件
  5. 子进程发送信号通知父进程表示完成,父进程更新统计信息

相关统计信息:

  • 上次fork子进程耗费的微秒数:info stats 命令,latest_fork_usec 项
  • 上次生成RDB的时间戳:info persistence 命令,rdb_last_save_time 项

RDB文件:

Redis加载损坏的RDB拒绝启动会打印日志Short read or OOM loading DB,使用 redis-check-dump 命令检测 RDB 文件,并获取错误报告。

二、AOF

记录每次的写命令,写入格式为Redis文本协议,重启时再重新执行AOF中的命令来达到恢复数据的目的,所以恢复速度相对 RDB 较慢。

配置项:

  • dir:保存路径
  • appendonly:是否开启
  • appendfilename:存储文件名
  • appendfsync:同步策略,always 每次写入调用 fsync,everysec 每秒调用 fsync,no 由系统配置决定调用 fsync 时机,一般30s

工作流程:

  1. 执行 AOF 请求,如果正在执行 AOF 重写或 bgsave 直接返回
  2. 父进程执行 fork 创建子进程,开销等同 bgsave,使用写时复制技术,子进程共享 fork 操作时的内存数据,接下来父进程的操作保存到重写缓冲区(aof_rewrite_buf)中
  3. 子进程批量写入新 AOF 文件中,每次批量写入大小由 aof-rewrite-incremental-fsync 配置控制,开启后每次写入32M,防止单次刷盘数据过大造成磁盘阻塞
  4. 新 AOF 文件重写完成后,发送信号给父进程,父进程更新统计信息
  5. 父进程将 aof_rewrite_buf 中的数据写入到新的 AOF 文件中
  6. 使用新的 AOF 文件替换老文件,重写完成

由于AOF追加阻塞造成丢失数据:

当策略为 everysec 时,丢失数据会有以下两种情况:

  • 如果距离上次同步成功时间(aof_last_rewrite_time_sec)超过2秒,Redis主线程将会阻塞
  • 如果距离上次同步成功时间在2秒内,会直接返回

如果发生上面任一种情况时宕机,会导致最多2秒的数据丢失。

发生阻塞时,会打印如下日志:

Asynchronous AOF fsync is taking too lang (disk is busy?).

同时会增加 aof_delayed_fsync 统计项次数(通过 info persistence 查看)

重写机制:

目的:降低AOF文件存储空间大小,加快重新加载速度

重写策略:

  • 超时的数据不再写入
  • 重复的无效的命令以最新的为准(比如:set why why,set why why1以后者为准)
  • 多条写命令合并为一个(比如:lpush list a、lpush list b、lpush list b,可以合并为lpush list a b c)

配置项:

  • auto-aof-rewrite-percentage:触发当前AOF文件大小和上一次重写后AOF文件大小的最小比值
  • auto-aof-rewrite-min-size:运行AOF重写时文件最小体积

相关统计信息:

  • aof_current_size:当前aof文件大小,通过info persistence命令查看
  • aof_base_siz:上次重写后AOF文件大小,通过info persistence命令查看

触发机制:

  • 手动触发:调用bgrewriteaof
  • 自动触发:aof_current_size > auto-aof-rewrite-min-size 并且 (aof_current_size - aof_base_size) / aof_base_size >= auto-aof-rewrite-percentage 时自动触发

三、混合持久化方式

由于 AOF 持久化方式在重启加载数据时效率远远不如 RDB 方式,所以 Redis 在4.0版本后引入了混合持久化方式,配置项为 aof-use-rdb-preamble,yes开启,策略为在生成或写入 AOF 文件时,将 RDB 数据写在前面,AOF 数据追加到后面,在每次启动时先加载 RDB,再加载 AOF ,下面为配置中的说明:

# When rewriting the AOF file, Redis is able to use an RDB preamble in the
# AOF file for faster rewrites and recoveries. When this option is turned
# on the rewritten AOF file is composed of two different stanzas:
#
#   [RDB file][AOF tail]
#
# When loading Redis recognizes that the AOF file starts with the "REDIS"
# string and loads the prefixed RDB file, and continues loading the AOF
# tail.
aof-use-rdb-preamble yes

四、多实例部署

Redis 单线程架构导致无法充分利用多核 CPU 特性,所以可以在一台机器上部署多个 Redis 实例。但是当多个实例同时开启 AOF 重写后,彼此之间会产生对 CPU 和 IO 的竞争,所以可以通过外部程序轮询,依此控制每个实例的 AOF 重写操作执行。

我们依赖的相关监控指标如下:

  • rdb_bgsave_in_progress:bgsave 子进程是否正在运行
  • rdb_last_save_time:当前运行 bgsave 的时间,-1表示未运行
  • aof_enabled:是否开启 AOF 
  • aof_rewrite_in_progress:AOF 重写子进程是否正在运行
  • aof_rewrite_scheduled:在 bgsave 结束后是否运行 AOF 重写
  • aof_current_rewrite_time_sec:当前运行 AOF 重写的时间,-1表示未运行
  • aof_current_size:AOF 文件当前字节数
  • aof_base_size:AOF 上次重写 rewrite 的字节数

代码实现:https://github.com/why444216978/php-redis-aof

运行前看一下 aof 文件更新时间:

why@localhost] /usr/local/var/db/redis$ll
total 48
-rw-r--r--  1 why  staff  9295  5  4 15:31 appendonly.aof
-rw-r--r--  1 why  staff  9295  5  4 15:26 dump.rdb

运行后再看一下 aof 文件更新时间:

[why@localhost] /usr/local/var/db/redis$ll
total 48
-rw-r--r--  1 why  staff  9295  5  4 17:19 appendonly.aof
-rw-r--r--  1 why  staff  9295  5  4 15:26 dump.rdb

成功!

 

 

标签:aof,持久,AOF,单机,Redis,rewrite,RDB,进程,重写
来源: https://blog.csdn.net/why444216978/article/details/105918282

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有